Browse Source

Add support for resolving properties, events and fields on local variables in IronPython.

pull/2/head
mrward 15 years ago
parent
commit
b24a863e68
  1. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
  2. 38
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClassMembers.cs
  3. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs
  4. 71
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMemberResolver.cs
  5. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs
  6. 14
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassPropertyTests.cs

1
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj

@ -94,6 +94,7 @@ @@ -94,6 +94,7 @@
<Compile Include="Src\MemberName.cs" />
<Compile Include="Src\PythonBuiltInModuleMemberName.cs" />
<Compile Include="Src\PythonClass.cs" />
<Compile Include="Src\PythonClassMembers.cs" />
<Compile Include="Src\PythonClassResolver.cs" />
<Compile Include="Src\PythonCodeCompletionItemProvider.cs" />
<Compile Include="Src\PythonCompilationUnit.cs" />

38
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClassMembers.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
// 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
{
public class PythonClassMembers
{
List<IMember> members;
public PythonClassMembers(IClass declaringType)
{
members = GetMembers(declaringType);
}
public IMember FindMember(string memberName)
{
foreach (IMember member in members) {
if (member.Name == memberName) {
return member;
}
}
return null;
}
List<IMember> GetMembers(IClass declaringType)
{
List<IMember> members = new List<IMember>();
members.AddRange(declaringType.Events);
members.AddRange(declaringType.Fields);
members.AddRange(declaringType.Properties);
return members;
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs

@ -12,8 +12,6 @@ namespace ICSharpCode.PythonBinding @@ -12,8 +12,6 @@ namespace ICSharpCode.PythonBinding
{
if (IsNormalKey(key)) {
return CompletionItemListKeyResult.NormalKey;
} else if (key == '(') {
return CompletionItemListKeyResult.NormalKey;
}
return base.ProcessInput(key);
}

71
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMemberResolver.cs

@ -13,83 +13,92 @@ namespace ICSharpCode.PythonBinding @@ -13,83 +13,92 @@ namespace ICSharpCode.PythonBinding
public class PythonMemberResolver : IPythonResolver
{
PythonClassResolver classResolver;
PythonLocalVariableResolver localVariableResolver;
PythonResolverContext resolverContext;
public PythonMemberResolver(PythonClassResolver classResolver)
public PythonMemberResolver(PythonClassResolver classResolver, PythonLocalVariableResolver localVariableResolver)
{
this.classResolver = classResolver;
this.localVariableResolver = localVariableResolver;
}
public ResolveResult Resolve(PythonResolverContext resolverContext)
{
IMember member = FindMember(resolverContext);
if (member != null) {
return CreateMemberResolveResult(member);
}
return null;
this.resolverContext = resolverContext;
IMember member = FindMember();
return CreateMemberResolveResult(member);
}
IMember FindMember(PythonResolverContext resolverContext)
IMember FindMember()
{
return FindMember(resolverContext, resolverContext.Expression);
return FindMember(resolverContext.Expression);
}
IMember FindMember(PythonResolverContext resolverContext, string expression)
IMember FindMember(string expression)
{
MemberName memberName = new MemberName(expression);
if (memberName.HasName) {
IClass c = FindClass(resolverContext, memberName.Type);
IClass c = FindClass(memberName.Type);
if (c != null) {
return FindMemberInClass(c, memberName.Name);
} else {
return FindMember(resolverContext, memberName);
return FindMemberInParent(memberName);
}
}
return null;
}
IClass FindClass(PythonResolverContext resolverContext, string className)
IClass FindClass(string className)
{
return classResolver.GetClass(resolverContext, className);
IClass c = FindClassFromClassResolver(className);
if (c != null) {
return c;
}
return FindClassFromLocalVariableResolver(className);
}
MemberResolveResult CreateMemberResolveResult(IMember member)
IClass FindClassFromClassResolver(string className)
{
return new MemberResolveResult(null, null, member);
return classResolver.GetClass(resolverContext, className);
}
IMember FindMemberInClass(IClass matchingClass, string memberName)
IClass FindClassFromLocalVariableResolver(string localVariableName)
{
List<IMember> members = GetMembers(matchingClass);
foreach (IMember member in members) {
if (member.Name == memberName) {
return member;
}
MemberName memberName = new MemberName(localVariableName);
if (!memberName.HasName) {
string typeName = localVariableResolver.Resolve(localVariableName, resolverContext.FileContent);
return FindClassFromClassResolver(typeName);
}
return null;
}
MemberResolveResult CreateMemberResolveResult(IMember member)
{
if (member != null) {
return new MemberResolveResult(null, null, member);
}
return null;
}
List<IMember> GetMembers(IClass c)
IMember FindMemberInClass(IClass matchingClass, string memberName)
{
List<IMember> members = new List<IMember>();
members.AddRange(c.Events);
members.AddRange(c.Fields);
members.AddRange(c.Properties);
return members;
PythonClassMembers classMembers = new PythonClassMembers(matchingClass);
return classMembers.FindMember(memberName);
}
IMember FindMember(PythonResolverContext resolverContext, MemberName memberName)
IMember FindMemberInParent(MemberName memberName)
{
IMember parentMember = FindMember(resolverContext, memberName.Type);
IMember parentMember = FindMember(memberName.Type);
if (parentMember != null) {
return FindMemberInParent(parentMember, memberName.Name);
}
return null;
}
IMember FindMemberInParent(IMember parentMember, string propertyName)
IMember FindMemberInParent(IMember parentMember, string memberName)
{
IClass parentMemberClass = parentMember.ReturnType.GetUnderlyingClass();
return FindMemberInClass(parentMemberClass, propertyName);
return FindMemberInClass(parentMemberClass, memberName);
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs

@ -27,8 +27,8 @@ namespace ICSharpCode.PythonBinding @@ -27,8 +27,8 @@ namespace ICSharpCode.PythonBinding
public PythonResolver()
{
methodResolver = new PythonMethodResolver(classResolver, standardModuleResolver);
memberResolver = new PythonMemberResolver(classResolver);
localVariableResolver = new PythonLocalVariableResolver(classResolver);
memberResolver = new PythonMemberResolver(classResolver, localVariableResolver);
resolvers.Add(importResolver);
resolvers.Add(classResolver);

14
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveClassPropertyTests.cs

@ -80,5 +80,19 @@ namespace PythonBinding.Tests.Resolver @@ -80,5 +80,19 @@ namespace PythonBinding.Tests.Resolver
Assert.AreEqual(nestedClassProperty, resolvedMember);
}
[Test]
public void Resolve_ExpressionIsForPropertyOnLocalVariable_MemberResolveResultResolvedTypeIsMyClassProperty()
{
CreateClassWithOneProperty();
string code =
"a = MyClass()\r\n" +
"a.MyProperty";
resolverHelper.Resolve("a.MyProperty", code);
IMember resolvedMember = resolverHelper.MemberResolveResult.ResolvedMember;
Assert.AreEqual(myClassProperty, resolvedMember);
}
}
}

Loading…
Cancel
Save