567 changed files with 3609 additions and 3884 deletions
@ -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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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