Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Resolve IronPython local variables up to the current expression line …

…and not beyond.
  • Loading branch information...
commit 938bc2dfdf8c8de3e49d176183db5bc0ddb55c70 1 parent c132891
@mrward mrward authored
View
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)
// 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.Collections.Generic;
using System.Text;
+using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Dom;
using IronPython;
using IronPython.Compiler;
using IronPython.Compiler.Ast;
-using IronPython.Runtime;
using IronPython.Hosting;
+using IronPython.Runtime;
using IronPython.Runtime.Exceptions;
+using Microsoft.Scripting;
+using Microsoft.Scripting.Hosting;
+using Microsoft.Scripting.Runtime;
namespace ICSharpCode.PythonBinding
{
@@ -54,7 +55,7 @@ string Resolve(string variableName, PythonAst ast)
{
this.variableName = variableName;
ast.Walk(this);
- return TypeName;
+ return TypeName;
}
public override bool Walk(AssignmentStatement node)
@@ -116,22 +117,28 @@ public static string GetTypeName(Expression node)
public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{
- return GetLocalVariable(resolverContext, expressionResult.Expression);
+ return GetLocalVariable(resolverContext, expressionResult);
}
/// <summary>
/// Tries to find the type that matches the local variable name.
/// </summary>
- LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext, string expression)
+ LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext, ExpressionResult expressionResult)
{
- PythonLocalVariableResolver resolver = new PythonLocalVariableResolver();
- string typeName = resolver.Resolve(expression, resolverContext.FileContent);
+ string code = GetLocalMethodCode(resolverContext.FileContent, expressionResult);
+ string typeName = Resolve(expressionResult.Expression, code);
if (typeName != null) {
- return CreateLocalResolveResult(typeName, expression, resolverContext);
+ return CreateLocalResolveResult(typeName, expressionResult.Expression, resolverContext);
}
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)
{
IClass resolvedClass = resolverContext.GetClass(typeName);
View
12 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs
@@ -23,21 +23,15 @@ public PythonResolverContext(ParseInformation parseInfo)
public PythonResolverContext(ParseInformation parseInfo, string fileContent)
{
this.fileContent = fileContent;
- GetCompilationUnits(parseInfo);
+ GetCompilationUnit(parseInfo);
GetProjectContent();
}
- void GetCompilationUnits(ParseInformation parseInfo)
- {
- compilationUnit = GetCompilationUnit(parseInfo);
- }
-
- ICompilationUnit GetCompilationUnit(ParseInformation parseInfo)
+ void GetCompilationUnit(ParseInformation parseInfo)
{
if (parseInfo != null) {
- return parseInfo.CompilationUnit;
+ compilationUnit = parseInfo.CompilationUnit;
}
- return null;
}
void GetProjectContent()
View
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)
using System;
+using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
using UnitTesting.Tests.Utils;
@@ -30,18 +31,81 @@ public void Init()
resolverHelper.ProjectContent.ClassesInProjectContent.Add(testClass);
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass);
+ }
+
+ [Test]
+ public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultVariableNameIsA()
+ {
string python =
"a = Test.Test1()\r\n" +
"a";
- resolverHelper.Resolve("a", python);
+ resolverHelper.Resolve("a", python);
+
+ string name = resolverHelper.LocalResolveResult.VariableName;
+
+ Assert.AreEqual("a", name);
}
-
+
[Test]
- public void ResolveResultVariableName()
+ public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultResolvedTypeIsTestClass()
{
- string name = resolverHelper.LocalResolveResult.VariableName;
- Assert.AreEqual("a", name);
+ string python =
+ "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);
}
}
}
View
5 src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonResolverTestsHelper.cs
@@ -44,6 +44,11 @@ public ResolveResult Resolve(string expression)
public ResolveResult Resolve(string expression, string code)
{
ExpressionResult expressionResult = new ExpressionResult(expression);
+ return Resolve(expressionResult, code);
+ }
+
+ public ResolveResult Resolve(ExpressionResult expressionResult, string code)
+ {
ResolveResult = Resolver.Resolve(expressionResult, ParseInfo, code);
return ResolveResult;
}
View
1  src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj
@@ -96,6 +96,7 @@
<Compile Include="Src\ScriptingDesignerGenerator.cs" />
<Compile Include="Src\ScriptingDesignerLoader.cs" />
<Compile Include="Src\ScriptingFileService.cs" />
+ <Compile Include="Src\ScriptingLocalMethod.cs" />
<Compile Include="Src\ScriptingNameCreationService.cs" />
<Compile Include="Src\ScriptingStyle.cs" />
<Compile Include="Src\ScriptingTextEditorViewContent.cs" />
View
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;
+ }
+ }
+}
View
2  src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj
@@ -62,6 +62,7 @@
<Folder Include="Configuration" />
<Folder Include="Console" />
<Folder Include="Designer" />
+ <Folder Include="Resolver" />
<Folder Include="Testing" />
<Folder Include="Utils" />
<Folder Include="Utils\Tests" />
@@ -104,6 +105,7 @@
<Compile Include="Designer\ScriptingCodeBuilderTests.cs" />
<Compile Include="Designer\ScriptingDesignerLoaderGetResourcesTests.cs" />
<Compile Include="Designer\ScriptingDesignerLoaderTests.cs" />
+ <Compile Include="Resolver\ScriptingLocalMethodTests.cs" />
<Compile Include="Testing\CreateTextWriterFromCreateTextWriterInfoTestFixture.cs" />
<Compile Include="Testing\CreateTextWriterInfoEqualsTestFixture.cs" />
<Compile Include="Utils\AddedComponent.cs" />
View
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);
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.