Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory-5.5.0/TypeSystem/InheritanceHelper.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 5.7 KB
Line 
1// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
2//
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:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
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.
18
19using System;
20using System.Collections.Generic;
21using System.Linq;
22using ICSharpCode.NRefactory.TypeSystem.Implementation;
23
24namespace ICSharpCode.NRefactory.TypeSystem
25{
26  /// <summary>
27  /// Provides helper methods for inheritance.
28  /// </summary>
29  public static class InheritanceHelper
30  {
31    // TODO: maybe these should be extension methods?
32    // or even part of the interface itself? (would allow for easy caching)
33   
34    #region GetBaseMember
35    /// <summary>
36    /// Gets the base member that has the same signature.
37    /// </summary>
38    public static IMember GetBaseMember(IMember member)
39    {
40      return GetBaseMembers(member, false).FirstOrDefault();
41    }
42
43    /// <summary>
44    /// Gets all base members that have the same signature.
45    /// </summary>
46    /// <returns>
47    /// List of base members with the same signature. The member from the derived-most base class is returned first.
48    /// </returns>
49    public static IEnumerable<IMember> GetBaseMembers(IMember member, bool includeImplementedInterfaces)
50    {
51      if (member == null)
52        throw new ArgumentNullException("member");
53
54      if (member.IsExplicitInterfaceImplementation && member.ImplementedInterfaceMembers.Count == 1) {
55        // C#-style explicit interface implementation
56        member = member.ImplementedInterfaceMembers[0];
57        yield return member;
58      }
59     
60      // Remove generic specialization
61      var substitution = member.Substitution;
62      member = member.MemberDefinition;
63     
64      if (member.DeclaringTypeDefinition == null) {
65        // For global methods, return empty list. (prevent SharpDevelop UDC crash 4524)
66        yield break;
67      }
68     
69      IEnumerable<IType> allBaseTypes;
70      if (includeImplementedInterfaces) {
71        allBaseTypes = member.DeclaringTypeDefinition.GetAllBaseTypes();
72      } else {
73        allBaseTypes = member.DeclaringTypeDefinition.GetNonInterfaceBaseTypes();
74      }
75      foreach (IType baseType in allBaseTypes.Reverse()) {
76        if (baseType == member.DeclaringTypeDefinition)
77          continue;
78
79        IEnumerable<IMember> baseMembers;
80        if (member.SymbolKind == SymbolKind.Accessor) {
81          baseMembers = baseType.GetAccessors(m => m.Name == member.Name && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers);
82        } else {
83          baseMembers = baseType.GetMembers(m => m.Name == member.Name && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers);
84        }
85        foreach (IMember baseMember in baseMembers) {
86          if (SignatureComparer.Ordinal.Equals(member, baseMember)) {
87            yield return baseMember.Specialize(substitution);
88          }
89        }
90      }
91    }
92    #endregion
93   
94    #region GetDerivedMember
95    /// <summary>
96    /// Finds the member declared in 'derivedType' that has the same signature (could override) 'baseMember'.
97    /// </summary>
98    public static IMember GetDerivedMember(IMember baseMember, ITypeDefinition derivedType)
99    {
100      if (baseMember == null)
101        throw new ArgumentNullException("baseMember");
102      if (derivedType == null)
103        throw new ArgumentNullException("derivedType");
104     
105      if (baseMember.Compilation != derivedType.Compilation)
106        throw new ArgumentException("baseMember and derivedType must be from the same compilation");
107     
108      baseMember = baseMember.MemberDefinition;
109      bool includeInterfaces = baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface;
110      IMethod method = baseMember as IMethod;
111      if (method != null) {
112        foreach (IMethod derivedMethod in derivedType.Methods) {
113          if (derivedMethod.Name == method.Name && derivedMethod.Parameters.Count == method.Parameters.Count) {
114            if (derivedMethod.TypeParameters.Count == method.TypeParameters.Count) {
115              // The method could override the base method:
116              if (GetBaseMembers(derivedMethod, includeInterfaces).Any(m => m.MemberDefinition == baseMember))
117                return derivedMethod;
118            }
119          }
120        }
121      }
122      IProperty property = baseMember as IProperty;
123      if (property != null) {
124        foreach (IProperty derivedProperty in derivedType.Properties) {
125          if (derivedProperty.Name == property.Name && derivedProperty.Parameters.Count == property.Parameters.Count) {
126            // The property could override the base property:
127            if (GetBaseMembers(derivedProperty, includeInterfaces).Any(m => m.MemberDefinition == baseMember))
128              return derivedProperty;
129          }
130        }
131      }
132      if (baseMember is IEvent) {
133        foreach (IEvent derivedEvent in derivedType.Events) {
134          if (derivedEvent.Name == baseMember.Name)
135            return derivedEvent;
136        }
137      }
138      if (baseMember is IField) {
139        foreach (IField derivedField in derivedType.Fields) {
140          if (derivedField.Name == baseMember.Name)
141            return derivedField;
142        }
143      }
144      return null;
145    }
146    #endregion
147  }
148}
Note: See TracBrowser for help on using the repository browser.