|
|
|
@ -67,13 +67,19 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -67,13 +67,19 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool getMembersBusy; |
|
|
|
|
// Required to prevent stack overflow when calling GetMethods() on a class with cyclic inheritance
|
|
|
|
|
// replaces old 'getMembersBusy' flag which wasn't thread-safe
|
|
|
|
|
[ThreadStatic] static BusyManager _busyManager; |
|
|
|
|
|
|
|
|
|
static BusyManager busyManager { |
|
|
|
|
get { return _busyManager ?? (_busyManager = new BusyManager()); } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override List<IMethod> GetMethods() |
|
|
|
|
{ |
|
|
|
|
if (getMembersBusy) return new List<IMethod>(); |
|
|
|
|
getMembersBusy = true; |
|
|
|
|
List<IMethod> l = new List<IMethod>(); |
|
|
|
|
using (var busyLock = busyManager.Enter(this)) { |
|
|
|
|
if (busyLock.Success) { |
|
|
|
|
l.AddRange(c.Methods); |
|
|
|
|
if (c.ClassType == ClassType.Interface) { |
|
|
|
|
if (c.BaseTypes.Count == 0) { |
|
|
|
@ -86,7 +92,8 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -86,7 +92,8 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
} else { |
|
|
|
|
AddMethodsFromBaseType(l, c.BaseType); |
|
|
|
|
} |
|
|
|
|
getMembersBusy = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return l; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -120,9 +127,9 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -120,9 +127,9 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
|
|
|
|
|
public override List<IProperty> GetProperties() |
|
|
|
|
{ |
|
|
|
|
if (getMembersBusy) return new List<IProperty>(); |
|
|
|
|
getMembersBusy = true; |
|
|
|
|
List<IProperty> l = new List<IProperty>(); |
|
|
|
|
using (var busyLock = busyManager.Enter(this)) { |
|
|
|
|
if (busyLock.Success) { |
|
|
|
|
l.AddRange(c.Properties); |
|
|
|
|
if (c.ClassType == ClassType.Interface) { |
|
|
|
|
foreach (IReturnType baseType in c.BaseTypes) { |
|
|
|
@ -131,7 +138,8 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -131,7 +138,8 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
} else { |
|
|
|
|
AddPropertiesFromBaseType(l, c.BaseType); |
|
|
|
|
} |
|
|
|
|
getMembersBusy = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return l; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -162,9 +170,9 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -162,9 +170,9 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
|
|
|
|
|
public override List<IField> GetFields() |
|
|
|
|
{ |
|
|
|
|
if (getMembersBusy) return new List<IField>(); |
|
|
|
|
getMembersBusy = true; |
|
|
|
|
List<IField> l = new List<IField>(); |
|
|
|
|
using (var busyLock = busyManager.Enter(this)) { |
|
|
|
|
if (busyLock.Success) { |
|
|
|
|
l.AddRange(c.Fields); |
|
|
|
|
if (c.ClassType == ClassType.Interface) { |
|
|
|
|
foreach (IReturnType baseType in c.BaseTypes) { |
|
|
|
@ -176,15 +184,16 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -176,15 +184,16 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
l.AddRange(baseType.GetFields()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
getMembersBusy = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return l; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override List<IEvent> GetEvents() |
|
|
|
|
{ |
|
|
|
|
if (getMembersBusy) return new List<IEvent>(); |
|
|
|
|
getMembersBusy = true; |
|
|
|
|
List<IEvent> l = new List<IEvent>(); |
|
|
|
|
using (var busyLock = busyManager.Enter(this)) { |
|
|
|
|
if (busyLock.Success) { |
|
|
|
|
l.AddRange(c.Events); |
|
|
|
|
if (c.ClassType == ClassType.Interface) { |
|
|
|
|
foreach (IReturnType baseType in c.BaseTypes) { |
|
|
|
@ -196,7 +205,8 @@ namespace ICSharpCode.SharpDevelop.Dom
@@ -196,7 +205,8 @@ namespace ICSharpCode.SharpDevelop.Dom
|
|
|
|
|
l.AddRange(baseType.GetEvents()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
getMembersBusy = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return l; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|