1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
20
using System.Collections.Generic;
22
using ICSharpCode.NRefactory.TypeSystem.Implementation;
24
namespace ICSharpCode.NRefactory.TypeSystem
27
/// Provides helper methods for inheritance.
29
public static class InheritanceHelper
31
// TODO: maybe these should be extension methods?
32
// or even part of the interface itself? (would allow for easy caching)
36
/// Gets the base member that has the same signature.
38
public static IMember GetBaseMember(IMember member)
40
return GetBaseMembers(member, false).FirstOrDefault();
44
/// Gets all base members that have the same signature.
47
/// List of base members with the same signature. The member from the derived-most base class is returned first.
49
public static IEnumerable<IMember> GetBaseMembers(IMember member, bool includeImplementedInterfaces)
52
throw new ArgumentNullException("member");
54
if (member.IsExplicitInterfaceImplementation && member.ImplementedInterfaceMembers.Count == 1) {
55
// C#-style explicit interface implementation
56
member = member.ImplementedInterfaceMembers[0];
60
SpecializedMember specializedMember = member as SpecializedMember;
61
member = member.MemberDefinition;
63
IEnumerable<IType> allBaseTypes;
64
if (includeImplementedInterfaces) {
65
allBaseTypes = member.DeclaringTypeDefinition.GetAllBaseTypes();
67
allBaseTypes = member.DeclaringTypeDefinition.GetNonInterfaceBaseTypes();
69
foreach (IType baseType in allBaseTypes.Reverse()) {
70
if (baseType == member.DeclaringTypeDefinition)
73
foreach (IMember baseMember in baseType.GetMembers(m => m.Name == member.Name, GetMemberOptions.IgnoreInheritedMembers)) {
74
if (SignatureComparer.Ordinal.Equals(member, baseMember)) {
75
if (specializedMember != null)
76
yield return SpecializedMember.Create(baseMember, specializedMember.Substitution);
78
yield return baseMember;
85
#region GetDerivedMember
87
/// Finds the member declared in 'derivedType' that has the same signature (could override) 'baseMember'.
89
public static IMember GetDerivedMember(IMember baseMember, ITypeDefinition derivedType)
91
if (baseMember == null)
92
throw new ArgumentNullException("baseMember");
93
if (derivedType == null)
94
throw new ArgumentNullException("derivedType");
96
baseMember = baseMember.MemberDefinition;
97
bool includeInterfaces = baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface;
98
IMethod method = baseMember as IMethod;
100
foreach (IMethod derivedMethod in derivedType.Methods) {
101
if (derivedMethod.Name == method.Name && derivedMethod.Parameters.Count == method.Parameters.Count) {
102
if (derivedMethod.TypeParameters.Count == method.TypeParameters.Count) {
103
// The method could override the base method:
104
if (GetBaseMembers(derivedMethod, includeInterfaces).Any(m => m.MemberDefinition == baseMember))
105
return derivedMethod;
110
IProperty property = baseMember as IProperty;
111
if (property != null) {
112
foreach (IProperty derivedProperty in derivedType.Properties) {
113
if (derivedProperty.Name == property.Name && derivedProperty.Parameters.Count == property.Parameters.Count) {
114
// The property could override the base property:
115
if (GetBaseMembers(derivedProperty, includeInterfaces).Any(m => m.MemberDefinition == baseMember))
116
return derivedProperty;
120
if (baseMember is IEvent) {
121
foreach (IEvent derivedEvent in derivedType.Events) {
122
if (derivedEvent.Name == baseMember.Name)
126
if (baseMember is IField) {
127
foreach (IField derivedField in derivedType.Fields) {
128
if (derivedField.Name == baseMember.Name)