Browse Source

Re-enable basic support for local variable code completion in IronPython.

pull/1/head
mrward 15 years ago
parent
commit
1b31c480d4
  1. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
  2. 73
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLocalVariableResolver.cs
  3. 41
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonParser.cs
  4. 45
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs
  5. 11
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs
  6. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  7. 78
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonLocalVariableResolverTests.cs
  8. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassEventTests.cs
  9. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassFieldTests.cs
  10. 41
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassInstanceWithNamespaceTestFixture.cs
  11. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassPropertyTests.cs
  12. 76
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveLocalClassInstanceTests.cs
  13. 19
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonResolverTestsHelper.cs

2
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj

@ -101,6 +101,7 @@
<Compile Include="Src\PythonFromImport.cs" /> <Compile Include="Src\PythonFromImport.cs" />
<Compile Include="Src\PythonImport.cs" /> <Compile Include="Src\PythonImport.cs" />
<Compile Include="Src\PythonLanguageBinding.cs" /> <Compile Include="Src\PythonLanguageBinding.cs" />
<Compile Include="Src\PythonLocalVariableResolver.cs" />
<Compile Include="Src\PythonMemberResolver.cs" /> <Compile Include="Src\PythonMemberResolver.cs" />
<Compile Include="Src\PythonMethodGroupResolveResult.cs" /> <Compile Include="Src\PythonMethodGroupResolveResult.cs" />
<Compile Include="Src\PythonMethodResolver.cs" /> <Compile Include="Src\PythonMethodResolver.cs" />
@ -163,7 +164,6 @@
<Compile Include="Src\RunDebugPythonCommand.cs" /> <Compile Include="Src\RunDebugPythonCommand.cs" />
<Compile Include="Src\RunPythonCommand.cs" /> <Compile Include="Src\RunPythonCommand.cs" />
<Compile Include="Src\PythonStandardModules.cs" /> <Compile Include="Src\PythonStandardModules.cs" />
<Compile Include="Src\PythonVariableResolver.cs" />
<Compile Include="Src\StringTextContentProvider.cs" /> <Compile Include="Src\StringTextContentProvider.cs" />
<None Include="..\..\RequiredLibraries\Chiron.exe.Config"> <None Include="..\..\RequiredLibraries\Chiron.exe.Config">
<Link>Chiron.exe.Config</Link> <Link>Chiron.exe.Config</Link>

73
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonVariableResolver.cs → src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLocalVariableResolver.cs

@ -21,17 +21,13 @@ namespace ICSharpCode.PythonBinding
/// <summary> /// <summary>
/// Determines the type of a variable. /// Determines the type of a variable.
/// </summary> /// </summary>
public class PythonVariableResolver : PythonWalker public class PythonLocalVariableResolver : PythonWalker, IPythonResolver
{ {
string variableName = String.Empty; string variableName = String.Empty;
string typeName; string typeName;
AssignmentStatement currentAssignStatement; AssignmentStatement currentAssignStatement;
bool foundVariableAssignment; bool foundVariableAssignment;
public PythonVariableResolver()
{
}
/// <summary> /// <summary>
/// The resolved type name. /// The resolved type name.
/// </summary> /// </summary>
@ -44,21 +40,23 @@ namespace ICSharpCode.PythonBinding
/// </summary> /// </summary>
/// <param name="variableName">Name of the variable.</param> /// <param name="variableName">Name of the variable.</param>
/// <param name="code">The python code containing the variable.</param> /// <param name="code">The python code containing the variable.</param>
public string Resolve(string variableName, string fileName, string code) public string Resolve(string variableName, string code)
{ {
if (code != null) { if (code != null) {
ScriptEngine scriptEngine = IronPython.Hosting.Python.CreateEngine(); PythonParser parser = new PythonParser();
PythonCompilerSink sink = new PythonCompilerSink(); PythonAst ast = parser.CreateAst("resolver.py", code);
SourceUnit source = DefaultContext.DefaultPythonContext.CreateFileUnit(fileName, code);
CompilerContext context = new CompilerContext(source, new PythonCompilerOptions(), sink);
Parser parser = Parser.CreateParser(context, new PythonOptions());
PythonAst ast = parser.ParseFile(false);
return Resolve(variableName, ast); return Resolve(variableName, ast);
} }
return null; return null;
} }
string Resolve(string variableName, PythonAst ast)
{
this.variableName = variableName;
ast.Walk(this);
return TypeName;
}
public override bool Walk(AssignmentStatement node) public override bool Walk(AssignmentStatement node)
{ {
currentAssignStatement = node; currentAssignStatement = node;
@ -136,11 +134,52 @@ namespace ICSharpCode.PythonBinding
return typeName.ToString(); return typeName.ToString();
} }
string Resolve(string variableName, PythonAst ast) public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{ {
this.variableName = variableName; return GetLocalVariable(resolverContext, expressionResult.Expression);
ast.Walk(this); }
return TypeName;
/// <summary>
/// Tries to find the type that matches the local variable name.
/// </summary>
LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext, string expression)
{
PythonLocalVariableResolver resolver = new PythonLocalVariableResolver();
string typeName = resolver.Resolve(expression, resolverContext.FileContent);
if (typeName != null) {
return CreateLocalResolveResult(typeName, expression, resolverContext);
}
return null;
}
LocalResolveResult CreateLocalResolveResult(string typeName, string identifier, PythonResolverContext resolverContext)
{
IClass resolvedClass = resolverContext.GetClass(typeName);
if (resolvedClass != null) {
return CreateLocalResolveResult(identifier, resolvedClass);
}
return null;
}
LocalResolveResult CreateLocalResolveResult(string identifier, IClass resolvedClass)
{
DefaultMethod dummyMethod = CreateDummyMethod();
DefaultField.LocalVariableField field = CreateLocalVariableField(identifier, resolvedClass, dummyMethod.DeclaringType);
return new LocalResolveResult(dummyMethod, field);
}
DefaultField.LocalVariableField CreateLocalVariableField(string identifier, IClass resolvedClass, IClass callingClass)
{
return new DefaultField.LocalVariableField(resolvedClass.DefaultReturnType,
identifier,
DomRegion.Empty,
callingClass);
}
DefaultMethod CreateDummyMethod()
{
DefaultClass dummyClass = new DefaultClass(DefaultCompilationUnit.DummyCompilationUnit, "Global");
return new DefaultMethod(dummyClass, String.Empty);
} }
} }
} }

41
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonParser.cs

@ -27,10 +27,6 @@ namespace ICSharpCode.PythonBinding
string[] lexerTags = new string[0]; string[] lexerTags = new string[0];
ScriptEngine scriptEngine; ScriptEngine scriptEngine;
public PythonParser()
{
}
public string[] LexerTags { public string[] LexerTags {
get { return lexerTags; } get { return lexerTags; }
set { lexerTags = value; } set { lexerTags = value; }
@ -40,10 +36,6 @@ namespace ICSharpCode.PythonBinding
get { return LanguageProperties.None; } get { return LanguageProperties.None; }
} }
/// <summary>
/// Creates a PythonExpressionFinder.
/// </summary>
public IExpressionFinder CreateExpressionFinder(string fileName) public IExpressionFinder CreateExpressionFinder(string fileName)
{ {
return new PythonExpressionFinder(); return new PythonExpressionFinder();
@ -75,14 +67,22 @@ namespace ICSharpCode.PythonBinding
/// <summary> /// <summary>
/// Parses a python file and creates a PythonAst. /// Parses a python file and creates a PythonAst.
/// </summary> /// </summary>
public PythonAst CreateAst(string fileName, ITextBuffer fileContent) public PythonAst CreateAst(string fileName, ITextBuffer textBuffer)
{
return CreateAst(fileName, textBuffer.Text);
}
/// <summary>
/// Parses a python file and creates a PythonAst.
/// </summary>
public PythonAst CreateAst(string fileName, string fileContent)
{ {
if (scriptEngine == null) { if (scriptEngine == null) {
scriptEngine = IronPython.Hosting.Python.CreateEngine(); scriptEngine = IronPython.Hosting.Python.CreateEngine();
} }
PythonCompilerSink sink = new PythonCompilerSink(); PythonCompilerSink sink = new PythonCompilerSink();
SourceUnit source = DefaultContext.DefaultPythonContext.CreateFileUnit(fileName, fileContent.Text); SourceUnit source = DefaultContext.DefaultPythonContext.CreateFileUnit(fileName, fileContent);
CompilerContext context = new CompilerContext(source, new PythonCompilerOptions(), sink); CompilerContext context = new CompilerContext(source, new PythonCompilerOptions(), sink);
using (Parser parser = Parser.CreateParser(context, new PythonOptions())) { using (Parser parser = Parser.CreateParser(context, new PythonOptions())) {
return parser.ParseFile(false); return parser.ParseFile(false);
@ -92,12 +92,24 @@ namespace ICSharpCode.PythonBinding
/// <summary> /// <summary>
/// Parses the python code and returns an ICompilationUnit. /// Parses the python code and returns an ICompilationUnit.
/// </summary> /// </summary>
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent) public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer textBuffer)
{ {
return Parse(projectContent, fileName, new StringTextBuffer(fileContent)); string fileContent = GetFileContent(textBuffer);
return Parse(projectContent, fileName, fileContent);
} }
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer fileContent) string GetFileContent(ITextBuffer textBuffer)
{
if (textBuffer != null) {
return textBuffer.Text;
}
return null;
}
/// <summary>
/// Parses the python code and returns an ICompilationUnit.
/// </summary>
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent)
{ {
if (fileContent != null) { if (fileContent != null) {
try { try {
@ -115,9 +127,6 @@ namespace ICSharpCode.PythonBinding
return compilationUnit; return compilationUnit;
} }
/// <summary>
/// Creates a new PythonResolver.
/// </summary>
public IResolver CreateResolver() public IResolver CreateResolver()
{ {
return new PythonResolver(); return new PythonResolver();

45
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs

@ -20,6 +20,7 @@ namespace ICSharpCode.PythonBinding
PythonSelfResolver selfResolver = new PythonSelfResolver(); PythonSelfResolver selfResolver = new PythonSelfResolver();
PythonMethodResolver methodResolver; PythonMethodResolver methodResolver;
PythonMemberResolver memberResolver; PythonMemberResolver memberResolver;
PythonLocalVariableResolver localVariableResolver = new PythonLocalVariableResolver();
List<IPythonResolver> resolvers = new List<IPythonResolver>(); List<IPythonResolver> resolvers = new List<IPythonResolver>();
@ -35,6 +36,7 @@ namespace ICSharpCode.PythonBinding
resolvers.Add(methodResolver); resolvers.Add(methodResolver);
resolvers.Add(selfResolver); resolvers.Add(selfResolver);
resolvers.Add(namespaceResolver); resolvers.Add(namespaceResolver);
resolvers.Add(localVariableResolver);
} }
public ResolveResult Resolve(ExpressionResult expressionResult, ParseInformation parseInfo, string fileContent) public ResolveResult Resolve(ExpressionResult expressionResult, ParseInformation parseInfo, string fileContent)
@ -43,7 +45,7 @@ namespace ICSharpCode.PythonBinding
return null; return null;
} }
resolverContext = new PythonResolverContext(parseInfo); resolverContext = new PythonResolverContext(parseInfo, fileContent);
if (!resolverContext.GetCallingMember(expressionResult.Region)) { if (!resolverContext.GetCallingMember(expressionResult.Region)) {
return null; return null;
} }
@ -59,13 +61,6 @@ namespace ICSharpCode.PythonBinding
return resolveResult; return resolveResult;
} }
} }
// // Search for a local variable.
// LocalResolveResult localResolveResult = GetLocalVariable(expressionResult.Expression, parseInfo.BestCompilationUnit.FileName, fileContent);
// if (localResolveResult != null) {
// return localResolveResult;
// }
return null; return null;
} }
@ -74,35 +69,25 @@ namespace ICSharpCode.PythonBinding
/// </summary> /// </summary>
public List<ICompletionEntry> CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context) public List<ICompletionEntry> CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context)
{ {
resolverContext = new PythonResolverContext(parseInfo); resolverContext = new PythonResolverContext(parseInfo, fileContent);
return CtrlSpace(resolverContext, context);
}
List<ICompletionEntry> CtrlSpace(PythonResolverContext resolverContext, ExpressionContext expressionContext)
{
if (resolverContext.HasProjectContent) { if (resolverContext.HasProjectContent) {
if (context == ExpressionContext.Namespace) { if (expressionContext == ExpressionContext.Namespace) {
PythonImportCompletion importCompletion = new PythonImportCompletion(resolverContext.ProjectContent); return GetImportCompletionItems(resolverContext.ProjectContent);
return importCompletion.GetCompletionItems();
} else {
return resolverContext.GetImportedTypes();
} }
return resolverContext.GetImportedTypes();
} }
return new List<ICompletionEntry>(); return new List<ICompletionEntry>();
} }
/// <summary> List<ICompletionEntry> GetImportCompletionItems(IProjectContent projectContent)
/// Tries to find the type that matches the local variable name.
/// </summary>
LocalResolveResult GetLocalVariable(string expression, string fileName, string fileContent)
{ {
// PythonVariableResolver resolver = new PythonVariableResolver(); PythonImportCompletion importCompletion = new PythonImportCompletion(projectContent);
// string typeName = resolver.Resolve(expression, fileName, fileContent); return importCompletion.GetCompletionItems();
// if (typeName != null) {
// IClass resolvedClass = GetClass(typeName);
// if (resolvedClass != null) {
// DefaultClass dummyClass = new DefaultClass(DefaultCompilationUnit.DummyCompilationUnit, "Global");
// DefaultMethod dummyMethod = new DefaultMethod(dummyClass, String.Empty);
// DefaultField.LocalVariableField field = new DefaultField.LocalVariableField(resolvedClass.DefaultReturnType, expression, DomRegion.Empty, dummyClass);
// return new LocalResolveResult(dummyMethod, field);
// }
// }
return null;
} }
} }
} }

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

@ -13,9 +13,16 @@ namespace ICSharpCode.PythonBinding
ICompilationUnit compilationUnit; ICompilationUnit compilationUnit;
IProjectContent projectContent; IProjectContent projectContent;
IClass callingClass; IClass callingClass;
string fileContent;
public PythonResolverContext(ParseInformation parseInfo) public PythonResolverContext(ParseInformation parseInfo)
: this(parseInfo, String.Empty)
{ {
}
public PythonResolverContext(ParseInformation parseInfo, string fileContent)
{
this.fileContent = fileContent;
GetCompilationUnits(parseInfo); GetCompilationUnits(parseInfo);
GetProjectContent(); GetProjectContent();
} }
@ -40,6 +47,10 @@ namespace ICSharpCode.PythonBinding
} }
} }
public string FileContent {
get { return fileContent; }
}
public IProjectContent ProjectContent { public IProjectContent ProjectContent {
get { return projectContent; } get { return projectContent; }
} }

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

@ -348,11 +348,11 @@
<Compile Include="Resolver\ImportModuleResolveResultTests.cs" /> <Compile Include="Resolver\ImportModuleResolveResultTests.cs" />
<Compile Include="Resolver\InvalidResolveInputsTestFixture.cs" /> <Compile Include="Resolver\InvalidResolveInputsTestFixture.cs" />
<Compile Include="Resolver\MemberNameTests.cs" /> <Compile Include="Resolver\MemberNameTests.cs" />
<Compile Include="Resolver\PythonLocalVariableResolverTests.cs" />
<Compile Include="Resolver\PythonSelfResolverTests.cs" /> <Compile Include="Resolver\PythonSelfResolverTests.cs" />
<Compile Include="Resolver\ResolveBuiltInRoundMethodTests.cs" /> <Compile Include="Resolver\ResolveBuiltInRoundMethodTests.cs" />
<Compile Include="Resolver\ResolveClassEventTests.cs" /> <Compile Include="Resolver\ResolveClassEventTests.cs" />
<Compile Include="Resolver\ResolveClassFieldTests.cs" /> <Compile Include="Resolver\ResolveClassFieldTests.cs" />
<Compile Include="Resolver\ResolveClassInstanceWithNamespaceTestFixture.cs" />
<Compile Include="Resolver\ResolveClassPropertyTests.cs" /> <Compile Include="Resolver\ResolveClassPropertyTests.cs" />
<Compile Include="Resolver\ResolveConsoleWriteLineTests.cs" /> <Compile Include="Resolver\ResolveConsoleWriteLineTests.cs" />
<Compile Include="Resolver\ResolveExitMethodFromSysImportExitAsMyExitTests.cs" /> <Compile Include="Resolver\ResolveExitMethodFromSysImportExitAsMyExitTests.cs" />

78
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonLocalVariableResolverTests.cs

@ -0,0 +1,78 @@
// 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 NUnit.Framework;
namespace PythonBinding.Tests.Resolver
{
[TestFixture]
public class PythonLocalVariableResolverTests
{
string typeName;
void Resolve(string variableName, string code)
{
PythonLocalVariableResolver resolver = new PythonLocalVariableResolver();
typeName = resolver.Resolve(variableName, code);
}
[Test]
public void Resolve_InstanceCreatedInCode_ReturnsInstanceType()
{
string code = "a = Class1()";
Resolve("a", code);
Assert.AreEqual("Class1", typeName);
}
/// <summary>
/// Tests that the NameExpression in the resolver is reset so the second assignment
/// does not override the first.
/// </summary>
[Test]
public void Resolve_TwoInstancesCreatedInCode_ReturnsFirstInstanceType()
{
string code =
"a = Class1()\r\n" +
"b = Class2()";
Resolve("a", code);
Assert.AreEqual("Class1", typeName);
}
[Test]
public void Resolve_VariableIsAssignedToString_ReturnsNull()
{
string code = "a = \"test\"";
Resolve("a", code);
Assert.IsNull(typeName);
}
[Test]
public void Resolve_CodeIsNull_ReturnsNull()
{
Resolve("a", null);
Assert.IsNull(typeName);
}
[Test]
public void Resolve_InstanceCreatedWithNamespace_ReturnsFullyQualifiedTypeName()
{
string code = "a = Test.Class1()";
Resolve("a", code);
Assert.AreEqual("Test.Class1", typeName);
}
[Test]
public void Resolve_InstanceCreatedWithTwoPartsToNamespace_ReturnsFullyQualifiedTypeName()
{
string code = "a = Root.Test.Class1()";
Resolve("a", code);
Assert.AreEqual("Root.Test.Class1", typeName);
}
}
}

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

@ -53,7 +53,7 @@ namespace PythonBinding.Tests.Resolver
{ {
CreateClassWithOneEvent(); CreateClassWithOneEvent();
resolverHelper.Resolve("MyClass.MyEvent"); resolverHelper.Resolve("MyClass.MyEvent");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(myClassEvent, resolvedMember); Assert.AreEqual(myClassEvent, resolvedMember);
} }
@ -64,7 +64,7 @@ namespace PythonBinding.Tests.Resolver
CreateClassWithOneEvent(); CreateClassWithOneEvent();
IEvent secondEvent = myClass.AddEvent("SecondEvent"); IEvent secondEvent = myClass.AddEvent("SecondEvent");
resolverHelper.Resolve("MyClass.SecondEvent"); resolverHelper.Resolve("MyClass.SecondEvent");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(secondEvent, resolvedMember); Assert.AreEqual(secondEvent, resolvedMember);
} }
@ -74,7 +74,7 @@ namespace PythonBinding.Tests.Resolver
{ {
CreateClassWithOneEvent(); CreateClassWithOneEvent();
resolverHelper.Resolve("MyClass.MyEvent.Target"); resolverHelper.Resolve("MyClass.MyEvent.Target");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(eventHandlerTargetProperty, resolvedMember); Assert.AreEqual(eventHandlerTargetProperty, resolvedMember);
} }

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassFieldTests.cs

@ -44,7 +44,7 @@ namespace PythonBinding.Tests.Resolver
{ {
CreateClassWithOneEvent(); CreateClassWithOneEvent();
resolverHelper.Resolve("MyClass.MyField"); resolverHelper.Resolve("MyClass.MyField");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(myClassField, resolvedMember); Assert.AreEqual(myClassField, resolvedMember);
} }

41
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassInstanceWithNamespaceTestFixture.cs

@ -1,41 +0,0 @@
// 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 System.Collections;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Resolver
{
/// <summary>
/// Given code:
///
/// a = Test.Class1()
///
/// Where Test is the namespace of the class, check that the type of "a" can be obtained
/// by the resolver.
/// </summary>
[TestFixture]
public class ResolveClassInstanceWithNamespaceTestFixture
{
[Test]
public void GetTypeOfInstance()
{
string code = "a = Test.Class1()";
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual("Test.Class1", resolver.Resolve("a", @"C:\Projects\Test\Test.py", code));
}
[Test]
public void GetTypeOfInstanceWithTwoNamespaces()
{
string code = "a = Root.Test.Class1()";
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual("Root.Test.Class1", resolver.Resolve("a", @"C:\Projects\Test\Test.py", code));
}
}
}

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

@ -54,7 +54,7 @@ namespace PythonBinding.Tests.Resolver
{ {
CreateClassWithOneProperty(); CreateClassWithOneProperty();
resolverHelper.Resolve("MyClass.MyProperty"); resolverHelper.Resolve("MyClass.MyProperty");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(myClassProperty, resolvedMember); Assert.AreEqual(myClassProperty, resolvedMember);
} }
@ -65,7 +65,7 @@ namespace PythonBinding.Tests.Resolver
CreateClassWithOneProperty(); CreateClassWithOneProperty();
myClass.InsertPropertyAtStart("ExtraProperty"); myClass.InsertPropertyAtStart("ExtraProperty");
resolverHelper.Resolve("MyClass.MyProperty"); resolverHelper.Resolve("MyClass.MyProperty");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(myClassProperty, resolvedMember); Assert.AreEqual(myClassProperty, resolvedMember);
} }
@ -76,7 +76,7 @@ namespace PythonBinding.Tests.Resolver
CreateClassWithOneProperty(); CreateClassWithOneProperty();
AddNestedPropertyToExistingProperty(); AddNestedPropertyToExistingProperty();
resolverHelper.Resolve("MyClass.MyProperty.MyNestedProperty"); resolverHelper.Resolve("MyClass.MyProperty.MyNestedProperty");
IMember resolvedMember = resolverHelper.MemberResultResult.ResolvedMember; IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(nestedClassProperty, resolvedMember); Assert.AreEqual(nestedClassProperty, resolvedMember);
} }

76
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveLocalClassInstanceTests.cs

@ -2,11 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework; using NUnit.Framework;
using PythonBinding.Tests;
using PythonBinding.Tests.Utils; using PythonBinding.Tests.Utils;
using UnitTesting.Tests.Utils; using UnitTesting.Tests.Utils;
@ -20,82 +16,32 @@ namespace PythonBinding.Tests.Resolver
/// Check that the type of "a" can be obtained by the resolver. /// Check that the type of "a" can be obtained by the resolver.
/// </summary> /// </summary>
[TestFixture] [TestFixture]
[Ignore("Disabled local variable resolution for SD 3.0")]
public class ResolveLocalClassInstanceTests public class ResolveLocalClassInstanceTests
{ {
PythonResolver resolver; PythonResolverTestsHelper resolverHelper;
ICSharpCode.Scripting.Tests.Utils.MockProjectContent mockProjectContent;
LocalResolveResult resolveResult;
MockClass testClass; MockClass testClass;
ICompilationUnit compilationUnit;
[TestFixtureSetUp] [SetUp]
public void SetUpFixture() public void Init()
{ {
resolver = new PythonResolver(); resolverHelper = new PythonResolverTestsHelper();
mockProjectContent = new ICSharpCode.Scripting.Tests.Utils.MockProjectContent(); testClass = resolverHelper.CreateClass("Test.Test1");
testClass = new MockClass(mockProjectContent, "Test.Test1"); resolverHelper.ProjectContent.ClassesInProjectContent.Add(testClass);
mockProjectContent.ClassesInProjectContent.Add(testClass); resolverHelper.ProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass);
mockProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass);
compilationUnit = new DefaultCompilationUnit(mockProjectContent);
compilationUnit.FileName = @"C:\Projects\Test\test.py";
ParseInformation parseInfo = new ParseInformation(compilationUnit);
string python = string python =
"a = Test1()\r\n" + "a = Test.Test1()\r\n" +
"a"; "a";
ExpressionResult expressionResult = new ExpressionResult("a", new DomRegion(2, 1), null, null);
resolveResult = resolver.Resolve(expressionResult, parseInfo, python) as LocalResolveResult;
}
[Test]
public void GetTypeOfInstance()
{
string code = "a = Class1()";
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual("Class1", resolver.Resolve("a", @"C:\Projects\Test\Test.py", code));
}
/// <summary>
/// Tests that the NameExpression in the resolver is reset so the second assignment
/// does not override the first.
/// </summary>
[Test]
public void DifferentTypeCreatedLast()
{
string code = "a = Class1()\r\n" +
"b = Class2()";
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual("Class1", resolver.Resolve("a", @"C:\Projects\Test\Test.py", code));
}
[Test] resolverHelper.Resolve("a", python);
public void StringAssignmentShouldNotResolve()
{
string code = "a = \"test\"";
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual(null, resolver.Resolve("a", @"C:\Projects\Test\Test.py", code));
}
[Test]
public void NullCodeShouldNotResolve()
{
PythonVariableResolver resolver = new PythonVariableResolver();
Assert.AreEqual(null, resolver.Resolve("a", @"C:\Projects\Test\Test.py", null));
}
[Test]
public void ResolveResultIsLocalResolveResult()
{
Assert.IsNotNull(resolveResult);
} }
[Test] [Test]
public void ResolveResultVariableName() public void ResolveResultVariableName()
{ {
Assert.AreEqual(resolveResult.VariableName, "a"); string name = resolverHelper.LocalResolveResult.VariableName;
Assert.AreEqual("a", name);
} }
} }
} }

19
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonResolverTestsHelper.cs

@ -14,7 +14,6 @@ namespace PythonBinding.Tests.Utils
public ScriptingUtils.MockProjectContent ProjectContent; public ScriptingUtils.MockProjectContent ProjectContent;
public DefaultCompilationUnit CompilationUnit; public DefaultCompilationUnit CompilationUnit;
public ParseInformation ParseInfo; public ParseInformation ParseInfo;
public PythonResolverContext Context;
public PythonResolver Resolver; public PythonResolver Resolver;
public ResolveResult ResolveResult; public ResolveResult ResolveResult;
@ -26,8 +25,6 @@ namespace PythonBinding.Tests.Utils
CompilationUnit = parser.Parse(ProjectContent, fileName, code) as DefaultCompilationUnit; CompilationUnit = parser.Parse(ProjectContent, fileName, code) as DefaultCompilationUnit;
ParseInfo = new ParseInformation(CompilationUnit); ParseInfo = new ParseInformation(CompilationUnit);
Context = new PythonResolverContext(ParseInfo);
Resolver = new PythonResolver(); Resolver = new PythonResolver();
} }
@ -39,14 +36,26 @@ namespace PythonBinding.Tests.Utils
public ResolveResult Resolve(string expression) public ResolveResult Resolve(string expression)
{ {
ExpressionResult expressionResult = new ExpressionResult(expression); ExpressionResult expressionResult = new ExpressionResult(expression);
ResolveResult = Resolver.Resolve(Context, expressionResult); PythonResolverContext context = new PythonResolverContext(ParseInfo);
ResolveResult = Resolver.Resolve(context, expressionResult);
return ResolveResult;
}
public ResolveResult Resolve(string expression, string code)
{
ExpressionResult expressionResult = new ExpressionResult(expression);
ResolveResult = Resolver.Resolve(expressionResult, ParseInfo, code);
return ResolveResult; return ResolveResult;
} }
public MemberResolveResult MemberResultResult { public MemberResolveResult MemberResolveResult {
get { return ResolveResult as MemberResolveResult; } get { return ResolveResult as MemberResolveResult; }
} }
public LocalResolveResult LocalResolveResult {
get { return ResolveResult as LocalResolveResult; }
}
public MockClass CreateClass(string name) public MockClass CreateClass(string name)
{ {
return new MockClass(ProjectContent, name); return new MockClass(ProjectContent, name);

Loading…
Cancel
Save