From aceae1f758f071b517bd5a6733740cb3624833b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Fri, 24 Jun 2011 11:26:35 +0200 Subject: [PATCH] implemented type parameter getmember methods. --- .../Implementation/DefaultTypeParameter.cs | 82 +++++++++++++++---- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs index 0ae7359001..ec8ce70079 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs @@ -250,40 +250,86 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public IEnumerable GetMethods(ITypeResolveContext context, Predicate filter = null) { - // TODO: get methods from constraints - IType objectType = context.GetTypeDefinition("System", "Object", 0, StringComparer.Ordinal); - IEnumerable objectMethods; - if (objectType != null) - objectMethods = objectType.GetMethods(context, filter); - else - objectMethods = EmptyList.Instance; - - // don't return static methods (those cannot be called from type parameter) - return objectMethods.Where(m => !m.IsStatic); + foreach (var baseType in GetNonCircularBaseTypes(context)) { + foreach (var m in baseType.GetMethods(context, filter)) { + if (!m.IsStatic) + yield return m; + } + } } public IEnumerable GetProperties(ITypeResolveContext context, Predicate filter = null) { - // TODO: get properties from constraints - return EmptyList.Instance; + foreach (var baseType in GetNonCircularBaseTypes(context)) { + foreach (var m in baseType.GetProperties(context, filter)) { + if (!m.IsStatic) + yield return m; + } + } } public IEnumerable GetFields(ITypeResolveContext context, Predicate filter = null) { - // TODO: get fields from constraints - return EmptyList.Instance; + foreach (var baseType in GetNonCircularBaseTypes(context)) { + foreach (var m in baseType.GetFields(context, filter)) { + if (!m.IsStatic) + yield return m; + } + } } public IEnumerable GetEvents(ITypeResolveContext context, Predicate filter = null) { - // TODO: get events from constraints - return EmptyList.Instance; + foreach (var baseType in GetNonCircularBaseTypes(context)) { + foreach (var m in baseType.GetEvents(context, filter)) { + if (!m.IsStatic) + yield return m; + } + } } public IEnumerable GetMembers(ITypeResolveContext context, Predicate filter = null) { - // TODO: get members from constraints - return GetMethods(context, filter); + foreach (var baseType in GetNonCircularBaseTypes(context)) { + foreach (var m in baseType.GetMembers(context, filter)) { + if (!m.IsStatic) + yield return m; + } + } + } + + // Problem with type parameter resolving - circular declarations + // void Example (S s, T t) where S : T where T : S + IEnumerable GetNonCircularBaseTypes(ITypeResolveContext context) + { + var result = this.GetBaseTypes(context).Where(bt => !IsCircular (context, bt)); + if (result.Any ()) + return result; + + // result may be empty, GetBaseTypes doesn't return object/struct when there are only constraints (even circular) as base types are available, + // but even when there are only circular references the default base type should be included. + IType defaultBaseType = context.GetTypeDefinition("System", HasValueTypeConstraint ? "ValueType" : "Object", 0, StringComparer.Ordinal); + if (defaultBaseType != null) + return new [] { defaultBaseType }; + return Enumerable.Empty (); + } + + bool IsCircular(ITypeResolveContext context, IType baseType) + { + var parameter = baseType as DefaultTypeParameter; + if (parameter == null) + return false; + var stack = new Stack(); + while (true) { + if (parameter == this) + return true; + foreach (DefaultTypeParameter parameterBaseType in parameter.GetNonCircularBaseTypes(context).Where(t => t is DefaultTypeParameter)) { + stack.Push(parameterBaseType); + } + if (stack.Count == 0) + return false; + parameter = stack.Pop(); + } } IEnumerable IType.GetNestedTypes(ITypeResolveContext context, Predicate filter)