Browse Source

Fix infinite recursion when resolving the base type of "class Test : Test.Base { public class Base {} }"

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
177fb85a00
  1. 10
      ICSharpCode.NRefactory.CSharp/Resolver/MemberTypeOrNamespaceReference.cs
  2. 8
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  3. 2
      ICSharpCode.NRefactory/Utils/BusyManager.cs

10
ICSharpCode.NRefactory.CSharp/Resolver/MemberTypeOrNamespaceReference.cs

@ -91,7 +91,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -91,7 +91,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
for (int i = 0; i < typeArgs.Length; i++) {
typeArgs[i] = typeArguments[i].Resolve(context);
}
ResolveResult rr = r.ResolveMemberType(targetRR, identifier, typeArgs);
ResolveResult rr;
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
rr = r.ResolveMemberType(targetRR, identifier, typeArgs);
} else {
// This can happen for "class Test : $Test.Base$ { public class Base {} }":
return ErrorResolveResult.UnknownError; // don't cache this error
}
}
if (cacheManager != null)
cacheManager.SetShared(this, rr);
return rr;

8
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -860,5 +860,13 @@ class B @@ -860,5 +860,13 @@ class B
Assert.AreEqual("T", m.Parameters[0].Type.Resolve(context).Name);
Assert.AreEqual("X", m.Parameters[1].Type.Resolve(context).Name);
}
[Test]
public void InheritingInnerClassShouldNotCauseStackOverflow()
{
string program = @"class Test : $Test.Base$, Test.ITest { public class Base {} interface ITest {} }";
var result = Resolve<TypeResolveResult>(program);
Assert.AreEqual("Test.Base", result.Type.FullName);
}
}
}

2
ICSharpCode.NRefactory/Utils/BusyManager.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.Utils @@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.Utils
/// However, using a simple 'bool busy' is not thread-safe, so we use a
/// thread-static BusyManager.
/// </summary>
static class BusyManager
public static class BusyManager
{
public struct BusyLock : IDisposable
{

Loading…
Cancel
Save