567 changed files with 3609 additions and 3884 deletions
@ -1,163 +0,0 @@
@@ -1,163 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using NUnit.Framework; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace UnitTesting.Tests.Utils.Tests |
||||
{ |
||||
[TestFixture] |
||||
public class MockClassTestFixture |
||||
{ |
||||
MockClass outerClass; |
||||
MockClass innerClass; |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithExpectedFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
Assert.AreEqual(fullyQualifiedName, c.FullyQualifiedName); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithFullyQualifiedNameHasMatchingDotNetName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
Assert.AreEqual(fullyQualifiedName, c.DotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithExpectedDotNetName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MyClass.InnerClass"; |
||||
string dotNetName = "MyNamespace.MyClass+InnerClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName, dotNetName); |
||||
Assert.AreEqual(dotNetName, c.DotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithNamespaceTakenFromFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MySubNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedNamespace = "MyNamespace.MySubNamespace"; |
||||
Assert.AreEqual(expectedNamespace, c.Namespace); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithNameTakenFromFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MySubNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedName = "MyClass"; |
||||
Assert.AreEqual(expectedName, c.Name); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassCreatedWithNoNamespaceInFullyQualifiedNameHasNamespaceOfEmptyString() |
||||
{ |
||||
string fullyQualifiedName = "MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedNamespace = String.Empty; |
||||
Assert.AreEqual(expectedNamespace, c.Namespace); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassHasCompilationUnit() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
Assert.IsNotNull(c.CompilationUnit); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassHasMockProjectContent() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
Assert.IsNotNull(c.ProjectContent as MockProjectContent); |
||||
} |
||||
|
||||
[Test] |
||||
public void CompoundClassIsClassItself() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
Assert.AreEqual(c, c.GetCompoundClass()); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassDefaultReturnTypeGetUnderlyingClassMatchesOriginalMockClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IReturnType returnType = c.DefaultReturnType; |
||||
Assert.AreEqual(c, returnType.GetUnderlyingClass()); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassWithInnerClassHasDeclaringTypeAsOuterClass() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
Assert.AreEqual(outerClass, innerClass.DeclaringType); |
||||
} |
||||
|
||||
void CreateClassWithInnerClass() |
||||
{ |
||||
outerClass = new MockClass("MyTests.A"); |
||||
innerClass = new MockClass("MyTests.A.InnerATest", "MyTests.A+InnerATest", outerClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void InnerClassGetCompoundClassReturnsInnerClass() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
Assert.AreEqual(innerClass, innerClass.GetCompoundClass()); |
||||
} |
||||
|
||||
[Test] |
||||
public void InnerClassAddedToOuterClassInnerClassCollection() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
Assert.AreEqual(innerClass, outerClass.InnerClasses[0]); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassAddedToBaseTypesBecomesBaseClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass baseClass = new MockClass(); |
||||
DefaultReturnType returnType = new DefaultReturnType(baseClass); |
||||
c.BaseTypes.Add(returnType); |
||||
Assert.AreEqual(baseClass, c.BaseClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void BaseClassPropertyReturnsClassAddedUsingAddBaseClassMethod() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass baseClass = new MockClass(); |
||||
c.AddBaseClass(baseClass); |
||||
Assert.AreEqual(baseClass, c.BaseClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void ClassWithProjectContentHasExpectedDotNetName() |
||||
{ |
||||
MockProjectContent projectContent = new MockProjectContent(); |
||||
string expectedName = "MyNamespace.MyTests"; |
||||
MockClass c = new MockClass(projectContent, expectedName); |
||||
Assert.AreEqual(expectedName, c.DotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetCompoundClassReturnsClassSetWithSetCompoundClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass compoundClass = new MockClass(); |
||||
c.SetCompoundClass(compoundClass); |
||||
Assert.AreEqual(compoundClass, c.GetCompoundClass()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
// 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.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using NUnit.Framework; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace UnitTesting.Tests.Utils.Tests |
||||
{ |
||||
[TestFixture] |
||||
public class MockClassTests |
||||
{ |
||||
MockClass outerClass; |
||||
MockClass innerClass; |
||||
|
||||
[Test] |
||||
public void FullyQualifiedName_NewInstanceCreatedWithFullyQualifiedName_ReturnsFullyQualifiedName() |
||||
{ |
||||
string expectedFullyQualifiedName = "MyNamespace.MyClass"; |
||||
MockClass c = new MockClass(expectedFullyQualifiedName); |
||||
string fullyQualifiedName = c.FullyQualifiedName; |
||||
Assert.AreEqual(expectedFullyQualifiedName, fullyQualifiedName); |
||||
} |
||||
|
||||
[Test] |
||||
public void DotNetName_NewInstanceCreatedWithFullyQualifiedName_ReturnsDotNetNameThatMatchesFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string dotNetName = c.DotNetName; |
||||
Assert.AreEqual(fullyQualifiedName, dotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void DotNetName_NewInstanceCreatedWithFullyQualifiedNameAndDotNetName_ReturnsExpectedDotNetName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MyClass.InnerClass"; |
||||
string expectedDotNetName = "MyNamespace.MyClass+InnerClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName, expectedDotNetName); |
||||
string dotNetName = c.DotNetName; |
||||
Assert.AreEqual(expectedDotNetName, dotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Namespace_NewInstanceCreatedWithFullyQualifiedName_ReturnsNamespaceTakenFromFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MySubNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedNamespace = "MyNamespace.MySubNamespace"; |
||||
string actualNamespace = c.Namespace; |
||||
Assert.AreEqual(expectedNamespace, actualNamespace); |
||||
} |
||||
|
||||
[Test] |
||||
public void Name_NewInstanceCreatedWithFullyQualifiedName_ReturnsNameTakenFromFullyQualifiedName() |
||||
{ |
||||
string fullyQualifiedName = "MyNamespace.MySubNamespace.MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedName = "MyClass"; |
||||
string name = c.Name; |
||||
Assert.AreEqual(expectedName, name); |
||||
} |
||||
|
||||
[Test] |
||||
public void Namesapce_NewInstanceCreatedWithFullyQualifiedNameWithNoNamespace_ReturnsEmptyStringAsNamespace() |
||||
{ |
||||
string fullyQualifiedName = "MyClass"; |
||||
MockClass c = new MockClass(fullyQualifiedName); |
||||
string expectedNamespace = String.Empty; |
||||
string actualNamespace = c.Namespace; |
||||
Assert.AreEqual(expectedNamespace, actualNamespace); |
||||
} |
||||
|
||||
[Test] |
||||
public void CompilationUnit_NewInstanceCreated_ReturnsNonNullCompilationUnit() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
ICompilationUnit unit = c.CompilationUnit; |
||||
Assert.IsNotNull(unit); |
||||
} |
||||
|
||||
[Test] |
||||
public void ProjectContent_NewInstanceCreated_ReturnsMockProjectContent() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockProjectContent projectContent = c.ProjectContent as MockProjectContent; |
||||
Assert.IsNotNull(projectContent); |
||||
} |
||||
|
||||
[Test] |
||||
public void CompoundClass_NewInstance_ReturnsClassItself() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IClass compoundClass = c.GetCompoundClass(); |
||||
Assert.AreEqual(c, compoundClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void DefaultReturnTypeGetUnderlyClass_NewInstance_ReturnsOriginalMockClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IReturnType returnType = c.DefaultReturnType; |
||||
IClass underlyingClass = returnType.GetUnderlyingClass(); |
||||
Assert.AreEqual(c, underlyingClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void DeclaringType_NewInstanceWithInnerClass_InnerClassHasOuterClassAsDeclaringType() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
IClass declaringType = innerClass.DeclaringType; |
||||
Assert.AreEqual(outerClass, declaringType); |
||||
} |
||||
|
||||
void CreateClassWithInnerClass() |
||||
{ |
||||
outerClass = new MockClass("MyTests.A"); |
||||
innerClass = new MockClass("MyTests.A.InnerATest", "MyTests.A+InnerATest", outerClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetCompoundClass_NewInstanceWithInnerClass_InnerClassReturnsInnerClassAsCompoundClass() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
IClass compoundClass = innerClass.GetCompoundClass(); |
||||
Assert.AreEqual(innerClass, compoundClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void InnerClasses_NewInstanceCreatedWithInnerClass_FirstClassInCollectionIsInnerClass() |
||||
{ |
||||
CreateClassWithInnerClass(); |
||||
IClass firstInnerClass = outerClass.InnerClasses[0]; |
||||
Assert.AreEqual(innerClass, firstInnerClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void BaseClass_ClassAddedToBaseTypes_ClassAddedToBaseTypesBecomesBaseClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass baseClass = new MockClass(); |
||||
DefaultReturnType returnType = new DefaultReturnType(baseClass); |
||||
c.BaseTypes.Add(returnType); |
||||
IClass actualBaseClass = c.BaseClass; |
||||
Assert.AreEqual(baseClass, actualBaseClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void BaseClass_AddBaseClassMethodCalled_ReturnsClassAddedUsingAddBaseClassMethod() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass baseClass = new MockClass(); |
||||
c.AddBaseClass(baseClass); |
||||
IClass actualBaseClass = c.BaseClass; |
||||
Assert.AreEqual(baseClass, actualBaseClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void DotNetName_NewInstanceCreatedWithProjectContent_ReturnsFullyQualifiedNameAsDotNetName() |
||||
{ |
||||
MockProjectContent projectContent = new MockProjectContent(); |
||||
string expectedName = "MyNamespace.MyTests"; |
||||
MockClass c = new MockClass(projectContent, expectedName); |
||||
string dotNetName = c.DotNetName; |
||||
Assert.AreEqual(expectedName, dotNetName); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetCompoundClass_SetCompoundClassMethodCalled_ReturnsClassPassedToSetCompoundClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
MockClass compoundClass = new MockClass(); |
||||
c.SetCompoundClass(compoundClass); |
||||
IClass actualCompoundClass = c.GetCompoundClass(); |
||||
Assert.AreEqual(compoundClass, actualCompoundClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddProperty_PassedPropertyName_AddsPropertyToClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
c.AddProperty("MyProperty"); |
||||
|
||||
IProperty property = c.Properties[0]; |
||||
string name = property.Name; |
||||
|
||||
Assert.AreEqual("MyProperty", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void InsertPropertyAtStart_PassedPropertyName_AddsPropertyAsFirstProperty() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
c.AddProperty("SecondProperty"); |
||||
c.InsertPropertyAtStart("FirstProperty"); |
||||
|
||||
IProperty property = c.Properties[0]; |
||||
string name = property.Name; |
||||
|
||||
Assert.AreEqual("FirstProperty", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddProperty_PassedPropertyName_ReturnsPropertyWithExpectedName() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IProperty property = c.AddProperty("MyProperty"); |
||||
string name = property.Name; |
||||
|
||||
Assert.AreEqual("MyProperty", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddEvent_PassedEventName_AddsEventToClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
c.AddEvent("MyEvent"); |
||||
|
||||
IEvent myEvent = c.Events[0]; |
||||
string name = myEvent.Name; |
||||
|
||||
Assert.AreEqual("MyEvent", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddEvent_PassedEventName_ReturnsEventWithExpectedName() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IEvent myEvent = c.AddEvent("MyEvent"); |
||||
string name = myEvent.Name; |
||||
|
||||
Assert.AreEqual("MyEvent", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddField_PassedFieldName_AddsFieldToClass() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
c.AddField("MyField"); |
||||
|
||||
IField myField = c.Fields[0]; |
||||
string name = myField.Name; |
||||
|
||||
Assert.AreEqual("MyField", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void AddField_PassedFieldName_ReturnsFieldWithExpectedName() |
||||
{ |
||||
MockClass c = new MockClass(); |
||||
IField myField = c.AddField("MyField"); |
||||
string name = myField.Name; |
||||
|
||||
Assert.AreEqual("MyField", name); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,182 @@
@@ -0,0 +1,182 @@
|
||||
// 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.Generic; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.Scripting; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using IronPython; |
||||
using IronPython.Compiler; |
||||
using IronPython.Compiler.Ast; |
||||
using IronPython.Hosting; |
||||
using IronPython.Runtime; |
||||
using IronPython.Runtime.Exceptions; |
||||
using Microsoft.Scripting; |
||||
using Microsoft.Scripting.Hosting; |
||||
using Microsoft.Scripting.Runtime; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Determines the type of a variable.
|
||||
/// </summary>
|
||||
public class PythonLocalVariableResolver : PythonWalker, IPythonResolver |
||||
{ |
||||
PythonClassResolver classResolver; |
||||
string variableName = String.Empty; |
||||
string typeName; |
||||
AssignmentStatement currentAssignStatement; |
||||
bool foundVariableAssignment; |
||||
|
||||
public PythonLocalVariableResolver(PythonClassResolver classResolver) |
||||
{ |
||||
this.classResolver = classResolver; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The resolved type name.
|
||||
/// </summary>
|
||||
public string TypeName { |
||||
get { return typeName; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Resolves the type of the variable name specified.
|
||||
/// </summary>
|
||||
/// <param name="variableName">Name of the variable.</param>
|
||||
/// <param name="code">The python code containing the variable.</param>
|
||||
public string Resolve(string variableName, string code) |
||||
{ |
||||
if (code != null) { |
||||
PythonParser parser = new PythonParser(); |
||||
PythonAst ast = parser.CreateAst("resolver.py", code); |
||||
return Resolve(variableName, ast); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
string Resolve(string variableName, PythonAst ast) |
||||
{ |
||||
this.variableName = variableName; |
||||
ast.Walk(this); |
||||
return TypeName; |
||||
} |
||||
|
||||
public override bool Walk(AssignmentStatement node) |
||||
{ |
||||
currentAssignStatement = node; |
||||
foundVariableAssignment = false; |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
public override bool Walk(NameExpression node) |
||||
{ |
||||
if (currentAssignStatement != null) { |
||||
string nodeName = node.Name; |
||||
if (nodeName == variableName) { |
||||
foundVariableAssignment = true; |
||||
} |
||||
} |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
public override bool Walk(CallExpression node) |
||||
{ |
||||
if (foundVariableAssignment) { |
||||
typeName = GetTypeName(node.Target); |
||||
currentAssignStatement = null; |
||||
foundVariableAssignment = false; |
||||
} |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the fully qualified name of the type from the expression.
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The expression is the first target of a call expression.
|
||||
///
|
||||
/// A call expression is a method or constructor call (right hand side of expression below):
|
||||
///
|
||||
/// a = Root.Test.Class1()
|
||||
///
|
||||
/// So the expression passed to this method will be a field expression in the
|
||||
/// above example which refers to Class1. The next target will be a field
|
||||
/// expression referring to Test. The The last target will be a name expression
|
||||
/// referring to Root.
|
||||
///
|
||||
/// If we have
|
||||
///
|
||||
/// a = Class1()
|
||||
///
|
||||
/// then the expression will be a name expression referring to Class1.
|
||||
/// </remarks>
|
||||
public static string GetTypeName(Expression node) |
||||
{ |
||||
NameExpression nameExpression = node as NameExpression; |
||||
if (nameExpression != null) { |
||||
return nameExpression.Name; |
||||
} |
||||
return PythonControlFieldExpression.GetMemberName(node as MemberExpression); |
||||
} |
||||
|
||||
public ResolveResult Resolve(PythonResolverContext resolverContext) |
||||
{ |
||||
return GetLocalVariable(resolverContext); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tries to find the type that matches the local variable name.
|
||||
/// </summary>
|
||||
LocalResolveResult GetLocalVariable(PythonResolverContext resolverContext) |
||||
{ |
||||
string code = GetLocalMethodCode(resolverContext); |
||||
string typeName = Resolve(resolverContext.Expression, code); |
||||
if (typeName != null) { |
||||
return CreateLocalResolveResult(typeName, resolverContext); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
string GetLocalMethodCode(PythonResolverContext resolverContext) |
||||
{ |
||||
ScriptingLocalMethod localMethod = new ScriptingLocalMethod(resolverContext.FileContent); |
||||
int beginLine = resolverContext.ExpressionRegion.BeginLine; |
||||
return localMethod.GetCode(beginLine); |
||||
} |
||||
|
||||
LocalResolveResult CreateLocalResolveResult(string typeName, PythonResolverContext resolverContext) |
||||
{ |
||||
IClass resolvedClass = classResolver.GetClass(resolverContext, typeName); |
||||
if (resolvedClass != null) { |
||||
string identifier = resolverContext.Expression; |
||||
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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
// 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.Generic; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Resolves properties, events and fields.
|
||||
/// </summary>
|
||||
public class PythonMemberResolver : IPythonResolver |
||||
{ |
||||
PythonClassResolver classResolver; |
||||
|
||||
public PythonMemberResolver(PythonClassResolver classResolver) |
||||
{ |
||||
this.classResolver = classResolver; |
||||
} |
||||
|
||||
public ResolveResult Resolve(PythonResolverContext resolverContext) |
||||
{ |
||||
IMember member = FindMember(resolverContext); |
||||
if (member != null) { |
||||
return CreateMemberResolveResult(member); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
IMember FindMember(PythonResolverContext resolverContext) |
||||
{ |
||||
return FindMember(resolverContext, resolverContext.Expression); |
||||
} |
||||
|
||||
IMember FindMember(PythonResolverContext resolverContext, string expression) |
||||
{ |
||||
MemberName memberName = new MemberName(expression); |
||||
if (memberName.HasName) { |
||||
IClass c = FindClass(resolverContext, memberName.Type); |
||||
if (c != null) { |
||||
return FindMemberInClass(c, memberName.Name); |
||||
} else { |
||||
return FindMember(resolverContext, memberName); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
IClass FindClass(PythonResolverContext resolverContext, string className) |
||||
{ |
||||
return classResolver.GetClass(resolverContext, className); |
||||
} |
||||
|
||||
MemberResolveResult CreateMemberResolveResult(IMember member) |
||||
{ |
||||
return new MemberResolveResult(null, null, member); |
||||
} |
||||
|
||||
IMember FindMemberInClass(IClass matchingClass, string memberName) |
||||
{ |
||||
List<IMember> members = GetMembers(matchingClass); |
||||
foreach (IMember member in members) { |
||||
if (member.Name == memberName) { |
||||
return member; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
List<IMember> GetMembers(IClass c) |
||||
{ |
||||
List<IMember> members = new List<IMember>(); |
||||
members.AddRange(c.Events); |
||||
members.AddRange(c.Fields); |
||||
members.AddRange(c.Properties); |
||||
return members; |
||||
} |
||||
|
||||
IMember FindMember(PythonResolverContext resolverContext, MemberName memberName) |
||||
{ |
||||
IMember parentMember = FindMember(resolverContext, memberName.Type); |
||||
if (parentMember != null) { |
||||
return FindMemberInParent(parentMember, memberName.Name); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
IMember FindMemberInParent(IMember parentMember, string propertyName) |
||||
{ |
||||
IClass parentMemberClass = parentMember.ReturnType.GetUnderlyingClass(); |
||||
return FindMemberInClass(parentMemberClass, propertyName); |
||||
} |
||||
} |
||||
} |
@ -1,146 +0,0 @@
@@ -1,146 +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 Microsoft.Scripting; |
||||
using Microsoft.Scripting.Hosting; |
||||
using Microsoft.Scripting.Runtime; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using IronPython; |
||||
using IronPython.Compiler; |
||||
using IronPython.Compiler.Ast; |
||||
using IronPython.Runtime; |
||||
using IronPython.Hosting; |
||||
using IronPython.Runtime.Exceptions; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Determines the type of a variable.
|
||||
/// </summary>
|
||||
public class PythonVariableResolver : PythonWalker |
||||
{ |
||||
string variableName = String.Empty; |
||||
string typeName; |
||||
AssignmentStatement currentAssignStatement; |
||||
bool foundVariableAssignment; |
||||
|
||||
public PythonVariableResolver() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The resolved type name.
|
||||
/// </summary>
|
||||
public string TypeName { |
||||
get { return typeName; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Resolves the type of the variable name specified.
|
||||
/// </summary>
|
||||
/// <param name="variableName">Name of the variable.</param>
|
||||
/// <param name="code">The python code containing the variable.</param>
|
||||
public string Resolve(string variableName, string fileName, string code) |
||||
{ |
||||
if (code != null) { |
||||
ScriptEngine scriptEngine = IronPython.Hosting.Python.CreateEngine(); |
||||
PythonCompilerSink sink = new PythonCompilerSink(); |
||||
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 null; |
||||
} |
||||
|
||||
public override bool Walk(AssignmentStatement node) |
||||
{ |
||||
currentAssignStatement = node; |
||||
foundVariableAssignment = false; |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
public override bool Walk(NameExpression node) |
||||
{ |
||||
if (currentAssignStatement != null) { |
||||
string nodeName = node.Name; |
||||
if (nodeName == variableName) { |
||||
foundVariableAssignment = true; |
||||
} |
||||
} |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
public override bool Walk(CallExpression node) |
||||
{ |
||||
if (foundVariableAssignment) { |
||||
typeName = GetTypeName(node.Target); |
||||
} |
||||
return base.Walk(node); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the fully qualified name of the type from the expression.
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The expression is the first target of a call expression.
|
||||
///
|
||||
/// A call expression is a method or constructor call (right hand side of expression below):
|
||||
///
|
||||
/// a = Root.Test.Class1()
|
||||
///
|
||||
/// So the expression passed to this method will be a field expression in the
|
||||
/// above example which refers to Class1. The next target will be a field
|
||||
/// expression referring to Test. The The last target will be a name expression
|
||||
/// referring to Root.
|
||||
///
|
||||
/// If we have
|
||||
///
|
||||
/// a = Class1()
|
||||
///
|
||||
/// then the expression will be a name expression referring to Class1.
|
||||
/// </remarks>
|
||||
static string GetTypeName(Expression node) |
||||
{ |
||||
// Collect the names that make up the type name.
|
||||
NameExpression nameExpression = null; |
||||
List<string> names = new List<string>(); |
||||
do { |
||||
nameExpression = node as NameExpression; |
||||
MemberExpression memberExpression = node as MemberExpression; |
||||
string name = String.Empty; |
||||
if (memberExpression != null) { |
||||
name = memberExpression.Name; |
||||
node = memberExpression.Target; |
||||
} else if (nameExpression != null) { |
||||
name = nameExpression.Name; |
||||
} |
||||
names.Add(name); |
||||
} while (nameExpression == null); |
||||
|
||||
// Create the fully qualified type name by adding the names
|
||||
// in reverse order.
|
||||
StringBuilder typeName = new StringBuilder(); |
||||
typeName.Append(names[names.Count - 1]); |
||||
for (int i = names.Count - 2; i >= 0; --i) { |
||||
typeName.Append('.'); |
||||
typeName.Append(names[i]); |
||||
} |
||||
return typeName.ToString(); |
||||
} |
||||
|
||||
string Resolve(string variableName, PythonAst ast) |
||||
{ |
||||
this.variableName = variableName; |
||||
ast.Walk(this); |
||||
return TypeName; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
// 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 IronPython.Compiler.Ast; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
[TestFixture] |
||||
public class PythonLocalVariableResolverTests |
||||
{ |
||||
string typeName; |
||||
|
||||
void Resolve(string variableName, string code) |
||||
{ |
||||
PythonClassResolver classResolver = new PythonClassResolver(); |
||||
PythonLocalVariableResolver resolver = new PythonLocalVariableResolver(classResolver); |
||||
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); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetTypeName_ExpressionIsNotNameOrMemberExpression_ReturnsEmptyStringAndDoesNotGetStuckInInfiniteLoop() |
||||
{ |
||||
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("a = 2"); |
||||
Expression expression = statement.Right; |
||||
string typeName = PythonLocalVariableResolver.GetTypeName(expression); |
||||
Assert.AreEqual(String.Empty, typeName); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
// 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.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Tests resolving events for the following classes:
|
||||
///
|
||||
/// public class MyClass
|
||||
/// {
|
||||
/// public event EventHandler MyEvent;
|
||||
/// }
|
||||
///
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class ResolveClassEventTests |
||||
{ |
||||
PythonResolverTestsHelper resolverHelper; |
||||
IEvent myClassEvent; |
||||
MockClass myClass; |
||||
IProperty eventHandlerTargetProperty; |
||||
|
||||
void CreateClassWithOneEvent() |
||||
{ |
||||
// Define imports.
|
||||
string code = |
||||
"from MyNamespace import MyClass"; |
||||
|
||||
resolverHelper = new PythonResolverTestsHelper(code); |
||||
myClass = resolverHelper.CreateClass("MyClass"); |
||||
myClassEvent = myClass.AddEvent("MyEvent"); |
||||
|
||||
AddEventHandlerClass(); |
||||
|
||||
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("MyNamespace.MyClass", myClass); |
||||
} |
||||
|
||||
void AddEventHandlerClass() |
||||
{ |
||||
MockClass eventHandlerClass = resolverHelper.CreateClass("EventHandler"); |
||||
eventHandlerTargetProperty = eventHandlerClass.AddProperty("Target"); |
||||
myClassEvent.ReturnType = new DefaultReturnType(eventHandlerClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForEventOnClass_MemberResolveResultResolvedTypeIsClassEvent() |
||||
{ |
||||
CreateClassWithOneEvent(); |
||||
resolverHelper.Resolve("MyClass.MyEvent"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(myClassEvent, resolvedMember); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForSecondEventOnClass_MemberResolveResultResolvedTypeIsSecondEvent() |
||||
{ |
||||
CreateClassWithOneEvent(); |
||||
IEvent secondEvent = myClass.AddEvent("SecondEvent"); |
||||
resolverHelper.Resolve("MyClass.SecondEvent"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(secondEvent, resolvedMember); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForEventHandlerTargetProperty_MemberResolveResultResolvedTypeIsEventHandlerTargetProperty() |
||||
{ |
||||
CreateClassWithOneEvent(); |
||||
resolverHelper.Resolve("MyClass.MyEvent.Target"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(eventHandlerTargetProperty, resolvedMember); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// 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.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Tests resolving events for the following classes:
|
||||
///
|
||||
/// public class MyClass
|
||||
/// {
|
||||
/// public int MyField
|
||||
/// }
|
||||
///
|
||||
/// public class MyClassWithFields
|
||||
/// {
|
||||
/// public int MyField = 0;
|
||||
/// }
|
||||
///
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class ResolveClassFieldTests |
||||
{ |
||||
PythonResolverTestsHelper resolverHelper; |
||||
IField myClassField; |
||||
MockClass myClass; |
||||
|
||||
void CreateClassWithOneEvent() |
||||
{ |
||||
resolverHelper = new PythonResolverTestsHelper(); |
||||
myClass = resolverHelper.CreateClass("MyClass"); |
||||
myClassField = myClass.AddField("MyField"); |
||||
|
||||
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("MyClass", myClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForFieldOnClass_MemberResolveResultResolvedTypeIsClassField() |
||||
{ |
||||
CreateClassWithOneEvent(); |
||||
resolverHelper.Resolve("MyClass.MyField"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(myClassField, resolvedMember); |
||||
} |
||||
} |
||||
} |
@ -1,41 +0,0 @@
@@ -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)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
// 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.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Tests resolving properties for the following classes:
|
||||
///
|
||||
/// public class MyClass
|
||||
/// {
|
||||
/// public MyNestedPropertyClass MyProperty { get; set; }
|
||||
/// }
|
||||
///
|
||||
/// public class MyNestedPropertyClass
|
||||
/// {
|
||||
/// public object MyNestedProperty { get; set; }
|
||||
/// }
|
||||
///
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class ResolveClassPropertyTests |
||||
{ |
||||
PythonResolverTestsHelper resolverHelper; |
||||
IProperty myClassProperty; |
||||
MockClass myClass; |
||||
IProperty nestedClassProperty; |
||||
|
||||
void CreateClassWithOneProperty() |
||||
{ |
||||
resolverHelper = new PythonResolverTestsHelper(); |
||||
myClass = resolverHelper.CreateClass("MyClass"); |
||||
myClassProperty = myClass.AddProperty("MyProperty"); |
||||
|
||||
AddNestedPropertyToExistingProperty(); |
||||
|
||||
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("MyClass", myClass); |
||||
} |
||||
|
||||
void AddNestedPropertyToExistingProperty() |
||||
{ |
||||
MockClass nestedPropertyClass = resolverHelper.CreateClass("MyNestedPropertyClass"); |
||||
nestedClassProperty = nestedPropertyClass.AddProperty("MyNestedProperty"); |
||||
myClassProperty.ReturnType = new DefaultReturnType(nestedPropertyClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForPropertyOnClassWithOneProperty_MemberResolveResultResolvedTypeIsMyClassProperty() |
||||
{ |
||||
CreateClassWithOneProperty(); |
||||
resolverHelper.Resolve("MyClass.MyProperty"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(myClassProperty, resolvedMember); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionIsForSecondPropertyOnClassWithTwoProperties_MemberResolveResultResolvedTypeIsSecondClassProperty() |
||||
{ |
||||
CreateClassWithOneProperty(); |
||||
myClass.InsertPropertyAtStart("ExtraProperty"); |
||||
resolverHelper.Resolve("MyClass.MyProperty"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(myClassProperty, resolvedMember); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_ExpressionRefersToNestedProperty_MemberResolveResultResolvedTypeIsNestedProperty() |
||||
{ |
||||
CreateClassWithOneProperty(); |
||||
AddNestedPropertyToExistingProperty(); |
||||
resolverHelper.Resolve("MyClass.MyProperty.MyNestedProperty"); |
||||
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember; |
||||
|
||||
Assert.AreEqual(nestedClassProperty, resolvedMember); |
||||
} |
||||
} |
||||
} |
@ -1,101 +0,0 @@
@@ -1,101 +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; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Given code:
|
||||
///
|
||||
/// a = Class1()
|
||||
///
|
||||
/// Check that the type of "a" can be obtained by the resolver.
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
[Ignore("Disabled local variable resolution for SD 3.0")] |
||||
public class ResolveLocalClassInstanceTestFixture |
||||
{ |
||||
PythonResolver resolver; |
||||
ICSharpCode.Scripting.Tests.Utils.MockProjectContent mockProjectContent; |
||||
LocalResolveResult resolveResult; |
||||
MockClass testClass; |
||||
ICompilationUnit compilationUnit; |
||||
|
||||
[TestFixtureSetUp] |
||||
public void SetUpFixture() |
||||
{ |
||||
resolver = new PythonResolver(); |
||||
|
||||
mockProjectContent = new ICSharpCode.Scripting.Tests.Utils.MockProjectContent(); |
||||
testClass = new MockClass(mockProjectContent, "Test.Test1"); |
||||
mockProjectContent.ClassesInProjectContent.Add(testClass); |
||||
mockProjectContent.ClassToReturnFromGetClass = testClass; |
||||
mockProjectContent.ClassNameForGetClass = "Test.Test1"; |
||||
|
||||
compilationUnit = new DefaultCompilationUnit(mockProjectContent); |
||||
compilationUnit.FileName = @"C:\Projects\Test\test.py"; |
||||
ParseInformation parseInfo = new ParseInformation(compilationUnit); |
||||
|
||||
string python = "a = Test1()\r\n" + |
||||
"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] |
||||
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] |
||||
public void ResolveResultVariableName() |
||||
{ |
||||
Assert.AreEqual(resolveResult.VariableName, "a"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,180 @@
@@ -0,0 +1,180 @@
|
||||
// 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.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
using UnitTesting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Given code:
|
||||
///
|
||||
/// a = Class1()
|
||||
///
|
||||
/// Check that the type of "a" can be obtained by the resolver.
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class ResolveLocalClassInstanceTests |
||||
{ |
||||
PythonResolverTestsHelper resolverHelper; |
||||
MockClass testClass; |
||||
|
||||
void CreateResolver() |
||||
{ |
||||
CreateResolver(String.Empty); |
||||
} |
||||
|
||||
void CreateResolver(string code) |
||||
{ |
||||
resolverHelper = new PythonResolverTestsHelper(code); |
||||
|
||||
testClass = resolverHelper.CreateClass("Test.Test1"); |
||||
resolverHelper.ProjectContent.ClassesInProjectContent.Add(testClass); |
||||
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("Test.Test1", testClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultVariableNameIsA() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
string python = |
||||
"a = Test.Test1()\r\n" + |
||||
"a"; |
||||
|
||||
resolverHelper.Resolve("a", python); |
||||
|
||||
string name = resolverHelper.LocalResolveResult.VariableName; |
||||
|
||||
Assert.AreEqual("a", name); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_LocalVariableIsCreatedOnPreviousLine_ResolveResultResolvedTypeIsTestClass() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
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() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
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: 2, |
||||
beginColumn: 0, |
||||
endLine: 2, |
||||
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() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
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: 2, |
||||
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_LocalVariableTypeIsImported_ResolveResultResolvedTypeDeterminedFromImportedTypes() |
||||
{ |
||||
string python = |
||||
"from MyNamespace import MyClass\r\n" + |
||||
"\r\n" + |
||||
"a = MyClass()\r\n" + |
||||
"a"; |
||||
|
||||
CreateResolver(python); |
||||
|
||||
MockClass myClass = resolverHelper.CreateClass("MyNamespace.MyClass"); |
||||
resolverHelper.ProjectContent.SetClassToReturnFromGetClass("MyNamespace.MyClass", myClass); |
||||
|
||||
resolverHelper.Resolve("a", python); |
||||
|
||||
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType; |
||||
IClass underlyingClass = resolvedType.GetUnderlyingClass(); |
||||
|
||||
Assert.AreEqual(myClass, underlyingClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_LocalVariableMethodIsCalledOnPreviousLine_ResolveResultResolvedTypeIsTestClass() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
string python = |
||||
"a = Test.Test1()\r\n" + |
||||
"a.foo()\r\n" + |
||||
"a"; |
||||
|
||||
resolverHelper.Resolve("a", python); |
||||
|
||||
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType; |
||||
IClass underlyingClass = resolvedType.GetUnderlyingClass(); |
||||
|
||||
Assert.AreEqual(testClass, underlyingClass); |
||||
} |
||||
|
||||
[Test] |
||||
public void Resolve_LocalVariableMethodIsCalledAfterVariableOnItsOwnOnPreviousLine_ResolveResultResolvedTypeIsTestClass() |
||||
{ |
||||
CreateResolver(); |
||||
|
||||
string python = |
||||
"a = Test.Test1()\r\n" + |
||||
"a\r\n" + |
||||
"a.foo()\r\n"; |
||||
|
||||
resolverHelper.Resolve("a", python); |
||||
|
||||
IReturnType resolvedType = resolverHelper.LocalResolveResult.ResolvedType; |
||||
IClass underlyingClass = resolvedType.GetUnderlyingClass(); |
||||
|
||||
Assert.AreEqual(testClass, underlyingClass); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
// 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 ICSharpCode.SharpDevelop.Dom; |
||||
using UnitTesting.Tests.Utils; |
||||
using ScriptingUtils = ICSharpCode.Scripting.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Utils |
||||
{ |
||||
public class PythonResolverTestsHelper |
||||
{ |
||||
public ScriptingUtils.MockProjectContent ProjectContent; |
||||
public DefaultCompilationUnit CompilationUnit; |
||||
public ParseInformation ParseInfo; |
||||
public PythonResolver Resolver; |
||||
public ResolveResult ResolveResult; |
||||
|
||||
public PythonResolverTestsHelper(string code) |
||||
{ |
||||
ProjectContent = new ScriptingUtils.MockProjectContent(); |
||||
PythonParser parser = new PythonParser(); |
||||
string fileName = @"test.py"; |
||||
CompilationUnit = parser.Parse(ProjectContent, fileName, code) as DefaultCompilationUnit; |
||||
|
||||
ParseInfo = new ParseInformation(CompilationUnit); |
||||
Resolver = new PythonResolver(); |
||||
} |
||||
|
||||
public PythonResolverTestsHelper() |
||||
: this(String.Empty) |
||||
{ |
||||
} |
||||
|
||||
public ResolveResult Resolve(string expression) |
||||
{ |
||||
ExpressionResult expressionResult = new ExpressionResult(expression); |
||||
PythonResolverContext context = new PythonResolverContext(ParseInfo, expressionResult, String.Empty); |
||||
ResolveResult = Resolver.Resolve(context); |
||||
return ResolveResult; |
||||
} |
||||
|
||||
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; |
||||
} |
||||
|
||||
public MemberResolveResult MemberResolveResult { |
||||
get { return ResolveResult as MemberResolveResult; } |
||||
} |
||||
|
||||
public LocalResolveResult LocalResolveResult { |
||||
get { return ResolveResult as LocalResolveResult; } |
||||
} |
||||
|
||||
public MethodGroupResolveResult MethodGroupResolveResult { |
||||
get { return ResolveResult as MethodGroupResolveResult; } |
||||
} |
||||
|
||||
public MockClass CreateClass(string name) |
||||
{ |
||||
return new MockClass(ProjectContent, name); |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue