Browse Source

Resolve IronPython local variables up to the current expression line and not beyond.

pull/1/head
mrward 16 years ago
parent
commit
938bc2dfdf
  1. 27
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLocalVariableResolver.cs
  2. 12
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs
  3. 74
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveLocalClassInstanceTests.cs
  4. 5
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonResolverTestsHelper.cs
  5. 1
      src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj
  6. 40
      src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingLocalMethod.cs
  7. 2
      src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj
  8. 91
      src/AddIns/BackendBindings/Scripting/Test/Resolver/ScriptingLocalMethodTests.cs

27
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLocalVariableResolver.cs

@ -1,20 +1,21 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // 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) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using IronPython; using IronPython;
using IronPython.Compiler; using IronPython.Compiler;
using IronPython.Compiler.Ast; using IronPython.Compiler.Ast;
using IronPython.Runtime;
using IronPython.Hosting; using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Exceptions; using IronPython.Runtime.Exceptions;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;
namespace ICSharpCode.PythonBinding namespace ICSharpCode.PythonBinding
{ {
@ -54,7 +55,7 @@ namespace ICSharpCode.PythonBinding
{ {
this.variableName = variableName; this.variableName = variableName;
ast.Walk(this); ast.Walk(this);
return TypeName; return TypeName;
} }
public override bool Walk(AssignmentStatement node) public override bool Walk(AssignmentStatement node)
@ -116,22 +117,28 @@ namespace ICSharpCode.PythonBinding
public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult) public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{ {
return GetLocalVariable(resolverContext, expressionResult.Expression); return GetLocalVariable(resolverContext, expressionResult);
} }
/// <summary> /// <summary>
/// Tries to find the type that matches the local variable name. /// Tries to find the type that matches the local variable name.
/// </summary> /// </summary>
LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext, string expression) LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{ {
PythonLocalVariableResolver resolver = new PythonLocalVariableResolver(); string code = GetLocalMethodCode(resolverContext.FileContent, expressionResult);
string typeName = resolver.Resolve(expression, resolverContext.FileContent); string typeName = Resolve(expressionResult.Expression, code);
if (typeName != null) { if (typeName != null) {
return CreateLocalResolveResult(typeName, expression, resolverContext); return CreateLocalResolveResult(typeName, expressionResult.Expression, resolverContext);
} }
return null; return null;
} }
string GetLocalMethodCode(string fullCode, ExpressionResult expressionResult)
{
ScriptingLocalMethod localMethod = new ScriptingLocalMethod(fullCode);
return localMethod.GetCode(expressionResult.Region.BeginLine);
}
LocalResolveResult CreateLocalResolveResult(string typeName, string identifier, PythonResolverContext resolverContext) LocalResolveResult CreateLocalResolveResult(string typeName, string identifier, PythonResolverContext resolverContext)
{ {
IClass resolvedClass = resolverContext.GetClass(typeName); IClass resolvedClass = resolverContext.GetClass(typeName);

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

@ -23,21 +23,15 @@ namespace ICSharpCode.PythonBinding
public PythonResolverContext(ParseInformation parseInfo, string fileContent) public PythonResolverContext(ParseInformation parseInfo, string fileContent)
{ {
this.fileContent = fileContent; this.fileContent = fileContent;
GetCompilationUnits(parseInfo); GetCompilationUnit(parseInfo);
GetProjectContent(); GetProjectContent();
} }
void GetCompilationUnits(ParseInformation parseInfo) void GetCompilationUnit(ParseInformation parseInfo)
{
compilationUnit = GetCompilationUnit(parseInfo);
}
ICompilationUnit GetCompilationUnit(ParseInformation parseInfo)
{ {
if (parseInfo != null) { if (parseInfo != null) {
return parseInfo.CompilationUnit; compilationUnit = parseInfo.CompilationUnit;
} }
return null;
} }
void GetProjectContent() void GetProjectContent()

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

@ -2,6 +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 ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework; using NUnit.Framework;
using PythonBinding.Tests.Utils; using PythonBinding.Tests.Utils;
using UnitTesting.Tests.Utils; using UnitTesting.Tests.Utils;
@ -30,18 +31,81 @@ namespace PythonBinding.Tests.Resolver
resolverHelper.ProjectContent.ClassesInProjectContent.Add(testClass); resolverHelper.ProjectContent.ClassesInProjectContent.Add(testClass);
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass); resolverHelper.ProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass);
}
[Test]
public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultVariableNameIsA()
{
string python = string python =
"a = Test.Test1()\r\n" + "a = Test.Test1()\r\n" +
"a"; "a";
resolverHelper.Resolve("a", python); resolverHelper.Resolve("a", python);
string name = resolverHelper.LocalResolveResult.VariableName;
Assert.AreEqual("a", name);
} }
[Test] [Test]
public void ResolveResultVariableName() public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultResolvedTypeIsTestClass()
{ {
string name = resolverHelper.LocalResolveResult.VariableName; string python =
Assert.AreEqual("a", name); "a = Test.Test1()\r\n" +
"a";
resolverHelper.Resolve("a", python);
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType;
IClass underlyingClass = resolvedType.GetUnderlyingClass();
Assert.AreEqual(testClass, underlyingClass);
}
[Test]
public void Resolve_LocalVariableIsReDefinedAfterLineBeingConsidered_ResolveResultResolvedTypeIsTestClass()
{
string python =
"a = Test.Test1()\r\n" +
"a\r\n" +
"a = Unknown.Unknown()\r\n";
ExpressionResult expression = new ExpressionResult("a");
expression.Region = new DomRegion(
beginLine: 1,
beginColumn: 0,
endLine: 1,
endColumn: 1);
resolverHelper.Resolve(expression, python);
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType;
IClass underlyingClass = resolvedType.GetUnderlyingClass();
Assert.AreEqual(testClass, underlyingClass);
}
[Test]
public void Resolve_LocalVariableIsReDefinedAfterLineBeingConsideredAndExpressionRegionEndLineIsMinusOne_ResolveResultResolvedTypeIsTestClass()
{
string python =
"a = Test.Test1()\r\n" +
"a\r\n" +
"a = Unknown.Unknown()\r\n";
ExpressionResult expression = new ExpressionResult("a");
expression.Region = new DomRegion(
beginLine: 1,
beginColumn: 0,
endLine: -1,
endColumn: 1);
resolverHelper.Resolve(expression, python);
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType;
IClass underlyingClass = resolvedType.GetUnderlyingClass();
Assert.AreEqual(testClass, underlyingClass);
} }
} }
} }

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

@ -44,6 +44,11 @@ namespace PythonBinding.Tests.Utils
public ResolveResult Resolve(string expression, string code) public ResolveResult Resolve(string expression, string code)
{ {
ExpressionResult expressionResult = new ExpressionResult(expression); ExpressionResult expressionResult = new ExpressionResult(expression);
return Resolve(expressionResult, code);
}
public ResolveResult Resolve(ExpressionResult expressionResult, string code)
{
ResolveResult = Resolver.Resolve(expressionResult, ParseInfo, code); ResolveResult = Resolver.Resolve(expressionResult, ParseInfo, code);
return ResolveResult; return ResolveResult;
} }

1
src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj

@ -96,6 +96,7 @@
<Compile Include="Src\ScriptingDesignerGenerator.cs" /> <Compile Include="Src\ScriptingDesignerGenerator.cs" />
<Compile Include="Src\ScriptingDesignerLoader.cs" /> <Compile Include="Src\ScriptingDesignerLoader.cs" />
<Compile Include="Src\ScriptingFileService.cs" /> <Compile Include="Src\ScriptingFileService.cs" />
<Compile Include="Src\ScriptingLocalMethod.cs" />
<Compile Include="Src\ScriptingNameCreationService.cs" /> <Compile Include="Src\ScriptingNameCreationService.cs" />
<Compile Include="Src\ScriptingStyle.cs" /> <Compile Include="Src\ScriptingStyle.cs" />
<Compile Include="Src\ScriptingTextEditorViewContent.cs" /> <Compile Include="Src\ScriptingTextEditorViewContent.cs" />

40
src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingLocalMethod.cs

@ -0,0 +1,40 @@
// 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;
namespace ICSharpCode.Scripting
{
/// <summary>
/// Used to extract the code for a method based on the range of lines.
/// </summary>
public class ScriptingLocalMethod
{
string code = String.Empty;
public ScriptingLocalMethod(string code)
{
if (code != null) {
this.code = code;
}
}
public string GetCode(int endLine)
{
int endIndex = FindIndexForEndOfLine(endLine);
if (endIndex > 0) {
return code.Substring(0, endIndex);
}
return code;
}
int FindIndexForEndOfLine(int line)
{
int index = 0;
for (int i = 0; i <= line; ++i) {
index = code.IndexOf('\n', index) + 1;
}
return index;
}
}
}

2
src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj

@ -62,6 +62,7 @@
<Folder Include="Configuration" /> <Folder Include="Configuration" />
<Folder Include="Console" /> <Folder Include="Console" />
<Folder Include="Designer" /> <Folder Include="Designer" />
<Folder Include="Resolver" />
<Folder Include="Testing" /> <Folder Include="Testing" />
<Folder Include="Utils" /> <Folder Include="Utils" />
<Folder Include="Utils\Tests" /> <Folder Include="Utils\Tests" />
@ -104,6 +105,7 @@
<Compile Include="Designer\ScriptingCodeBuilderTests.cs" /> <Compile Include="Designer\ScriptingCodeBuilderTests.cs" />
<Compile Include="Designer\ScriptingDesignerLoaderGetResourcesTests.cs" /> <Compile Include="Designer\ScriptingDesignerLoaderGetResourcesTests.cs" />
<Compile Include="Designer\ScriptingDesignerLoaderTests.cs" /> <Compile Include="Designer\ScriptingDesignerLoaderTests.cs" />
<Compile Include="Resolver\ScriptingLocalMethodTests.cs" />
<Compile Include="Testing\CreateTextWriterFromCreateTextWriterInfoTestFixture.cs" /> <Compile Include="Testing\CreateTextWriterFromCreateTextWriterInfoTestFixture.cs" />
<Compile Include="Testing\CreateTextWriterInfoEqualsTestFixture.cs" /> <Compile Include="Testing\CreateTextWriterInfoEqualsTestFixture.cs" />
<Compile Include="Utils\AddedComponent.cs" /> <Compile Include="Utils\AddedComponent.cs" />

91
src/AddIns/BackendBindings/Scripting/Test/Resolver/ScriptingLocalMethodTests.cs

@ -0,0 +1,91 @@
// 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 NUnit.Framework;
using ICSharpCode.Scripting;
namespace ICSharpCode.Scripting.Tests.Resolver
{
[TestFixture]
public class ScriptingLocalMethodTests
{
ScriptingLocalMethod method;
void CreateLocalMethod(string code)
{
method = new ScriptingLocalMethod(code);
}
[Test]
public void GetCode_EndLineIsZeroAndTwoLinesOfCode_ReturnsFirstLineOfCode()
{
string fullCode =
"first\r\n" +
"second";
CreateLocalMethod(fullCode);
int endLine = 0;
string code = method.GetCode(endLine);
string expectedCode = "first\r\n";
Assert.AreEqual(expectedCode, code);
}
[Test]
public void GetCode_EndLineIsOneAndThreeLinesOfCode_ReturnsFirstTwoLinesOfCode()
{
string fullCode =
"first\r\n" +
"second\r\n" +
"third";
CreateLocalMethod(fullCode);
int endLine = 1;
string code = method.GetCode(endLine);
string expectedCode =
"first\r\n" +
"second\r\n";
Assert.AreEqual(expectedCode, code);
}
[Test]
public void GetCode_EndLineIsOneAndTwoLinesOfCode_ReturnsFirstTwoLinesOfCode()
{
string fullCode =
"first\r\n" +
"second";
CreateLocalMethod(fullCode);
int endLine = 1;
string code = method.GetCode(endLine);
string expectedCode =
"first\r\n" +
"second";
Assert.AreEqual(expectedCode, code);
}
[Test]
public void GetCode_EndLineIsOneAndCodeIsNull_ReturnsEmptyString()
{
string fullCode = null;
CreateLocalMethod(fullCode);
int endLine = 1;
string code = method.GetCode(endLine);
string expectedCode = String.Empty;
Assert.AreEqual(expectedCode, code);
}
}
}
Loading…
Cancel
Save