Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
Resolve IronPython local variables up to the current expression line …
Browse files Browse the repository at this point in the history
…and not beyond.
  • Loading branch information
mrward committed Sep 25, 2010
1 parent c132891 commit 938bc2d
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 24 deletions.
@@ -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
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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()
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
}
Expand Up @@ -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;
}
Expand Down
Expand Up @@ -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" />
Expand Down
@@ -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;
}
}
}
Expand Up @@ -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" />
Expand Down Expand Up @@ -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" />
Expand Down
@@ -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);
}
}
}

0 comments on commit 938bc2d

Please sign in to comment.