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 @@
<Compile Include="Src\MemberName.cs" /> <Compile Include="Src\MemberName.cs" />
<Compile Include="Src\PythonBuiltInModuleMemberName.cs" /> <Compile Include="Src\PythonBuiltInModuleMemberName.cs" />
<Compile Include="Src\PythonClass.cs" /> <Compile Include="Src\PythonClass.cs" />
<Compile Include="Src\PythonClassMembers.cs" />
<Compile Include="Src\PythonClassResolver.cs" /> <Compile Include="Src\PythonClassResolver.cs" />
<Compile Include="Src\PythonCodeCompletionItemProvider.cs" /> <Compile Include="Src\PythonCodeCompletionItemProvider.cs" />
<Compile Include="Src\PythonCompilationUnit.cs" /> <Compile Include="Src\PythonCompilationUnit.cs" />

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

@ -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
{ {
if (IsNormalKey(key)) { if (IsNormalKey(key)) {
return CompletionItemListKeyResult.NormalKey; return CompletionItemListKeyResult.NormalKey;
} else if (key == '(') {
return CompletionItemListKeyResult.NormalKey;
} }
return base.ProcessInput(key); return base.ProcessInput(key);
} }

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

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

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

@ -80,5 +80,19 @@ namespace PythonBinding.Tests.Resolver
Assert.AreEqual(nestedClassProperty, resolvedMember); 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