Browse Source

Improved python code completion for .NET library imports.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@5472 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Matt Ward 16 years ago
parent
commit
e6b79a0398
  1. 39
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClassResolver.cs
  2. 13
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonNamespaceResolver.cs
  3. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs
  4. 5
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  5. 59
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleFromSystemImportEverythingFixture.cs
  6. 85
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleTestFixture.cs
  7. 14
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSystemNamespaceTestFixture.cs
  8. 47
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSystemNamespaceWithMissingImportTestFixture.cs
  9. 55
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveTextBoxFromSystemWindowsFormsImportTextBoxTestFixture.cs
  10. 55
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveTextBoxFromSystemWindowsFormsImportedAsMyTextBoxTestFixture.cs
  11. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveUnknownNamespaceTestFixture.cs
  12. 55
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/Tests/MockProjectContentTests.cs

39
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClassResolver.cs

@ -36,12 +36,49 @@ namespace ICSharpCode.PythonBinding @@ -36,12 +36,49 @@ namespace ICSharpCode.PythonBinding
return matchedClass;
}
return context.GetImportedClass(name);
matchedClass = GetClassFromImportedNames(context, name);
if (matchedClass != null) {
return matchedClass;
}
matchedClass = GetClassFromNamespaceThatImportsEverything(context, name);
if (matchedClass != null) {
return matchedClass;
}
return null;
}
TypeResolveResult CreateTypeResolveResult(IClass c)
{
return new TypeResolveResult(null, null, c);
}
IClass GetClassFromImportedNames(PythonResolverContext context, string name)
{
string moduleName = context.GetModuleForImportedName(name);
if (moduleName != null) {
name = context.UnaliasImportedName(name);
string fullyQualifiedName = GetQualifiedClassName(moduleName, name);
return context.GetClass(fullyQualifiedName);
}
return null;
}
string GetQualifiedClassName(string namespacePrefix, string className)
{
return namespacePrefix + "." + className;
}
IClass GetClassFromNamespaceThatImportsEverything(PythonResolverContext context, string name)
{
foreach (string moduleName in context.GetModulesThatImportEverything()) {
string fullyQualifiedName = GetQualifiedClassName(moduleName, name);
IClass matchedClass = context.GetClass(fullyQualifiedName);
if (matchedClass != null) {
return matchedClass;
}
}
return null;
}
}
}

13
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonNamespaceResolver.cs

@ -18,9 +18,18 @@ namespace ICSharpCode.PythonBinding @@ -18,9 +18,18 @@ namespace ICSharpCode.PythonBinding
public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{
if (!resolverContext.HasImport(expressionResult.Expression)) {
return null;
}
string actualNamespace = resolverContext.UnaliasImportedModuleName(expressionResult.Expression);
if (resolverContext.NamespaceExists(actualNamespace)) {
return new NamespaceResolveResult(null, null, actualNamespace);
return CreateNamespaceResolveResultIfNamespaceExists(resolverContext, actualNamespace);
}
ResolveResult CreateNamespaceResolveResultIfNamespaceExists(PythonResolverContext resolverContext, string namespaceName)
{
if (resolverContext.NamespaceExistsInProjectReferences(namespaceName)) {
return new NamespaceResolveResult(null, null, namespaceName);
}
return null;
}

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.PythonBinding @@ -54,7 +54,7 @@ namespace ICSharpCode.PythonBinding
get { return callingClass; }
}
public bool NamespaceExists(string name)
public bool NamespaceExistsInProjectReferences(string name)
{
return projectContent.NamespaceExists(name);
}
@ -158,7 +158,7 @@ namespace ICSharpCode.PythonBinding @@ -158,7 +158,7 @@ namespace ICSharpCode.PythonBinding
/// <param name="name">The unqualified class name.</param>
public IClass GetImportedClass(string name)
{
foreach (Object obj in GetImportedTypes()) {
foreach (object obj in GetImportedTypes()) {
IClass c = obj as IClass;
if ((c != null) && IsSameClassName(name, c.Name)) {
return c;

5
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

@ -361,12 +361,12 @@ @@ -361,12 +361,12 @@
<Compile Include="Resolver\MemberNameTests.cs" />
<Compile Include="Resolver\ResolveBuiltInRoundMethodTestFixture.cs" />
<Compile Include="Resolver\ResolveClassInstanceWithNamespaceTestFixture.cs" />
<Compile Include="Resolver\ResolveConsoleTestFixture.cs" />
<Compile Include="Resolver\ResolveConsoleWriteLineTestFixture.cs" />
<Compile Include="Resolver\ResolveExitMethodFromSysImportExitAsMyExitTestFixture.cs" />
<Compile Include="Resolver\ResolveExitMethodFromSysImportExitTestFixture.cs" />
<Compile Include="Resolver\ResolveFromImportTestFixture.cs" />
<Compile Include="Resolver\ResolveFromMathImportedMathModuleCompletionItemsTestFixture.cs" />
<Compile Include="Resolver\ResolveConsoleFromSystemImportEverythingFixture.cs" />
<Compile Include="Resolver\ResolveImportsTestFixture.cs" />
<Compile Include="Resolver\ResolveLocalClassInstanceTestFixture.cs" />
<Compile Include="Resolver\ResolveMethodFromUnknownImportAllTestFixture.cs" />
@ -389,9 +389,12 @@ @@ -389,9 +389,12 @@
<Compile Include="Resolver\ResolveSystemImportedAsMySystemTestFixture.cs" />
<Compile Include="Resolver\ResolveSystemImportTestFixture.cs" />
<Compile Include="Resolver\ResolveSystemNamespaceTestFixture.cs" />
<Compile Include="Resolver\ResolveSystemNamespaceWithMissingImportTestFixture.cs" />
<Compile Include="Resolver\ResolveTanMethodFromMathImportAllTestFixture.cs" />
<Compile Include="Resolver\ResolveTanMethodFromMathImportCosAndTanTestFixture.cs" />
<Compile Include="Resolver\ResolveTestFixtureBase.cs" />
<Compile Include="Resolver\ResolveTextBoxFromSystemWindowsFormsImportedAsMyTextBoxTestFixture.cs" />
<Compile Include="Resolver\ResolveTextBoxFromSystemWindowsFormsImportTextBoxTestFixture.cs" />
<Compile Include="Resolver\ResolveUnknownNamespaceTestFixture.cs" />
<Compile Include="RunPythonCommandTestFixture.cs" />
<Compile Include="Utils\AddedComponent.cs" />

59
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleFromSystemImportEverythingFixture.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
[TestFixture]
public class ResolveFromSystemImportEverythingFixture : ResolveTestFixtureBase
{
MockClass consoleClass;
protected override ExpressionResult GetExpressionResult()
{
consoleClass = new MockClass(projectContent, "System.Console");
projectContent.ClassToReturnFromGetClass = consoleClass;
projectContent.ClassNameForGetClass = "System.Console";
projectContent.AddExistingNamespaceContents("System", new ArrayList());
return new ExpressionResult("Console", ExpressionContext.Default);
}
protected override string GetPythonScript()
{
return
"from System import *\r\n" +
"Console\r\n" +
"\r\n";
}
[Test]
public void ResolveResultResolvedClassIsConsoleClass()
{
Assert.AreEqual(consoleClass, TypeResolveResult.ResolvedClass);
}
TypeResolveResult TypeResolveResult {
get { return (TypeResolveResult)resolveResult; }
}
[Test]
public void ProjectContentNamespaceExistsReturnsTrueForSystem()
{
Assert.IsTrue(projectContent.NamespaceExists("System"));
}
}
}

85
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleTestFixture.cs

@ -1,85 +0,0 @@ @@ -1,85 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
/// <summary>
/// Tests the PythonResolver correctly resolves the expression:
/// "Console." when the System namespace is imported.
/// </summary>
[TestFixture]
public class ResolveConsoleTestFixture
{
PythonResolver resolver;
MockProjectContent mockProjectContent;
ResolveResult resolveResult;
MockClass testClass;
ICompilationUnit compilationUnit;
MockClass systemConsoleClass;
[TestFixtureSetUp]
public void SetUpFixture()
{
resolver = new PythonResolver();
ParseInformation parseInfo = new ParseInformation();
mockProjectContent = new MockProjectContent();
// Do not return any class from GetClass call. This method
// will not return anything in the real class since the
// type is not fully qualified with its namespace.
mockProjectContent.ClassToReturnFromGetClass = null;
systemConsoleClass = new MockClass(mockProjectContent, "System.Console");
mockProjectContent.ClassesInProjectContent.Add(systemConsoleClass);
compilationUnit = new DefaultCompilationUnit(mockProjectContent) { ErrorsDuringCompile = true };
testClass = new MockClass(compilationUnit, "Test");
compilationUnit.Classes.Add(testClass);
parseInfo.SetCompilationUnit(compilationUnit);
string python = "import System\r\n" +
"class Test:\r\n" +
"\tdef __init__(self):\r\n" +
"\tConsole\r\n";
ExpressionResult expressionResult = new ExpressionResult("Console", new DomRegion(3, 7), null, null);
resolveResult = resolver.Resolve(expressionResult, parseInfo, python);
}
[Test]
public void IsTypeResolveResult()
{
Assert.IsInstanceOf(typeof(TypeResolveResult), resolveResult);
}
[Test]
public void ResolvedClass()
{
TypeResolveResult typeResolveResult = resolveResult as TypeResolveResult;
Assert.AreEqual(systemConsoleClass, typeResolveResult.ResolvedClass);
}
//
// [Test]
// public void IsGetClassCalled()
// {
// Assert.IsTrue(mockProjectContent.GetClassCalled);
// }
//
// [Test]
// public void GetClassName()
// {
// Assert.AreEqual("System.Console", mockProjectContent.GetClassName);
// }
}
}

14
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSystemNamespaceTestFixture.cs

@ -30,22 +30,22 @@ namespace PythonBinding.Tests.Resolver @@ -30,22 +30,22 @@ namespace PythonBinding.Tests.Resolver
public void SetUpFixture()
{
resolver = new PythonResolver();
ParseInformation parseInfo = new ParseInformation();
mockProjectContent = new MockProjectContent();
mockProjectContent.AddExistingNamespaceContents("System", new ArrayList());
DefaultCompilationUnit cu = new DefaultCompilationUnit(mockProjectContent);
cu.ErrorsDuringCompile = true;
cu.FileName = @"C:\Projects\Test\test.py";
parseInfo.SetCompilationUnit(cu);
string python =
"import System\r\n" +
"class Test:\r\n" +
" def __init__(self):\r\n" +
" System.\r\n";
ExpressionResult expressionResult = new ExpressionResult("System", new DomRegion(3, 2), null, null);
PythonParser parser = new PythonParser();
string fileName = @"C:\Projects\Test\test.py";
DefaultCompilationUnit cu = parser.Parse(mockProjectContent, fileName, python) as DefaultCompilationUnit;
cu.ErrorsDuringCompile = true;
ParseInformation parseInfo = new ParseInformation(cu);
ExpressionResult expressionResult = new ExpressionResult("System", new DomRegion(4, 2), null, null);
resolveResult = resolver.Resolve(expressionResult, parseInfo, python) as NamespaceResolveResult;
}

47
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSystemNamespaceWithMissingImportTestFixture.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
[TestFixture]
public class ResolveSystemNamespaceWithMissingImportTestFixture : ResolveTestFixtureBase
{
protected override ExpressionResult GetExpressionResult()
{
MockClass systemConsoleClass = new MockClass(projectContent, "System.Console");
ArrayList items = new ArrayList();
items.Add(systemConsoleClass);
projectContent.AddExistingNamespaceContents("System", items);
return new ExpressionResult("System", ExpressionContext.Default);
}
protected override string GetPythonScript()
{
return "System\r\n";
}
[Test]
public void ResolveResultIsNullSinceSystemNamespaceIsNotImported()
{
Assert.IsNull(resolveResult);
}
[Test]
public void ProjectContentNamespaceExistsReturnsTrueForSystemNamespace()
{
Assert.IsTrue(projectContent.NamespaceExists("System"));
}
}
}

55
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveTextBoxFromSystemWindowsFormsImportTextBoxTestFixture.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
[TestFixture]
public class ResolveTextBoxFromSystemWindowsFormsImportTextBoxTestFixture : ResolveTestFixtureBase
{
protected override ExpressionResult GetExpressionResult()
{
MockClass textBoxClass = new MockClass(projectContent, "System.Windows.Forms.TextBox");
projectContent.ClassToReturnFromGetClass = textBoxClass;
projectContent.ClassNameForGetClass = "System.Windows.Forms.TextBox";
return new ExpressionResult("TextBox", ExpressionContext.Default);
}
protected override string GetPythonScript()
{
return
"from System.Windows.Forms import TextBox\r\n" +
"TextBox\r\n" +
"\r\n";
}
[Test]
public void ResolveResultIsTypeResolveResult()
{
Assert.IsTrue(resolveResult is TypeResolveResult);
}
[Test]
public void ResolveResultResolveClassNameIsTextBox()
{
Assert.AreEqual("TextBox", TypeResolveResult.ResolvedClass.Name);
}
TypeResolveResult TypeResolveResult {
get { return (TypeResolveResult)resolveResult; }
}
}
}

55
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveTextBoxFromSystemWindowsFormsImportedAsMyTextBoxTestFixture.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
[TestFixture]
public class ResolveTextBoxFromSystemWindowsFormsImportedAsMyTextBoxTestFixture : ResolveTestFixtureBase
{
protected override ExpressionResult GetExpressionResult()
{
MockClass textBoxClass = new MockClass(projectContent, "System.Windows.Forms.TextBox");
projectContent.ClassToReturnFromGetClass = textBoxClass;
projectContent.ClassNameForGetClass = "System.Windows.Forms.TextBox";
return new ExpressionResult("MyTextBox", ExpressionContext.Default);
}
protected override string GetPythonScript()
{
return
"from System.Windows.Forms import TextBox as MyTextBox\r\n" +
"MyTextBox\r\n" +
"\r\n";
}
[Test]
public void ResolveResultIsTypeResolveResult()
{
Assert.IsTrue(resolveResult is TypeResolveResult);
}
[Test]
public void ResolveResultResolveClassNameIsTextBox()
{
Assert.AreEqual("TextBox", TypeResolveResult.ResolvedClass.Name);
}
TypeResolveResult TypeResolveResult {
get { return (TypeResolveResult)resolveResult; }
}
}
}

6
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveUnknownNamespaceTestFixture.cs

@ -43,11 +43,5 @@ namespace PythonBinding.Tests.Resolver @@ -43,11 +43,5 @@ namespace PythonBinding.Tests.Resolver
{
Assert.IsNull(resolveResult);
}
[Test]
public void NamespaceExistsCalled()
{
Assert.IsTrue(projectContent.NamespaceExistsCalled);
}
}
}

55
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/Tests/MockProjectContentTests.cs

@ -142,5 +142,60 @@ namespace PythonBinding.Tests.Utils.Tests @@ -142,5 +142,60 @@ namespace PythonBinding.Tests.Utils.Tests
projectContent.NamespaceExists("System");
Assert.IsTrue(projectContent.NamespaceExistsCalled);
}
[Test]
public void GetClassReturnsNullByDefault()
{
Assert.IsNull(projectContent.GetClass("test", 0));
}
[Test]
public void GetClassNameReturnsClassNamePassedToGetClassMethod()
{
projectContent.GetClass("abc", 0);
Assert.AreEqual("abc", projectContent.GetClassName);
}
[Test]
public void GetClassCalledIsFalseByDefault()
{
Assert.IsFalse(projectContent.GetClassCalled);
}
[Test]
public void GetClassCalledIsTrueAfterGetClassCalled()
{
projectContent.GetClass("abc", 0);
Assert.IsTrue(projectContent.GetClassCalled);
}
[Test]
public void GetClassReturnsClassEvenIfClassNameDoesNotMatchAndNoClassNameForGetClassSpecified()
{
MockClass c = new MockClass(projectContent, "test");
projectContent.ClassToReturnFromGetClass = c;
Assert.AreEqual(c, projectContent.GetClass("abcdef", 0));
}
[Test]
public void GetClassReturnsNullIfClassNameDoesNotMatchClassNameForGetClassProperty()
{
MockClass c = new MockClass(projectContent, "test");
projectContent.ClassToReturnFromGetClass = c;
projectContent.ClassNameForGetClass = "test";
Assert.IsNull(projectContent.GetClass("abcdef", 0));
}
[Test]
public void GetClassReturnsClassIfClassNameMatchesClassNameForGetClassProperty()
{
MockClass c = new MockClass(projectContent, "test");
projectContent.ClassToReturnFromGetClass = c;
projectContent.ClassNameForGetClass = "test";
Assert.AreEqual(c, projectContent.GetClass("test", 0));
}
}
}

Loading…
Cancel
Save