diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/MemberLookup.cs b/ICSharpCode.NRefactory.CSharp/Resolver/MemberLookup.cs index 4496bc673f..3f17a32e37 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/MemberLookup.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/MemberLookup.cs @@ -66,7 +66,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public bool IsProtectedAccessAllowed(IType targetType) { ITypeDefinition typeDef = targetType.GetDefinition(); - return typeDef != null && typeDef.IsDerivedFrom(currentTypeDefinition); + if (typeDef == null) + return false; + for (ITypeDefinition c = currentTypeDefinition; c != null; c = c.DeclaringTypeDefinition) { + if (typeDef.IsDerivedFrom(c)) + return true; + } + return false; } /// @@ -126,7 +132,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // PERF: this might hurt performance as this method is called several times (once for each member) // make sure resolving base types is cheap (caches?) or cache within the MemberLookup instance - if (allowProtectedAccess && currentTypeDefinition.IsDerivedFrom(entity.DeclaringTypeDefinition)) + if (allowProtectedAccess && t.IsDerivedFrom(entity.DeclaringTypeDefinition)) return true; } return false; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs index 9e37b36040..ac5f5c8b57 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs @@ -261,5 +261,21 @@ public struct C { Assert.AreEqual("C`1[[`0]]", rr.Arguments[0].Type.ReflectionName); Assert.AreEqual("C`1[[`0]]", rr.Arguments[1].Type.ReflectionName); } + + [Test] + public void ProtectedFieldInOuterClass() + { + string program = @"using System; +class Base { + protected int X; +} +class Derived : Base { + class Inner { + public int M(Derived d) { return $d.X$; } +}}"; + var rr = Resolve(program); + Assert.IsFalse(rr.IsError); + Assert.AreEqual("Base.X", rr.Member.FullName); + } } }