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;
23
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
26
/// References an entity by its type and name.
27
/// This class can be used to refer to all members except for constructors and explicit interface implementations.
30
/// Resolving a DefaultMemberReference requires a context that provides enough information for resolving the declaring type reference
31
/// and the parameter types references.
34
public sealed class DefaultMemberReference : IMemberReference, ISupportsInterning
36
EntityType entityType;
37
ITypeReference typeReference;
39
int typeParameterCount;
40
IList<ITypeReference> parameterTypes;
42
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null)
44
if (typeReference == null)
45
throw new ArgumentNullException("typeReference");
47
throw new ArgumentNullException("name");
48
if (typeParameterCount != 0 && entityType != EntityType.Method)
49
throw new ArgumentException("Type parameter count > 0 is only supported for methods.");
50
this.entityType = entityType;
51
this.typeReference = typeReference;
53
this.typeParameterCount = typeParameterCount;
54
this.parameterTypes = parameterTypes ?? EmptyList<ITypeReference>.Instance;
57
public ITypeReference DeclaringTypeReference {
58
get { return typeReference; }
61
public IMember Resolve(ITypeResolveContext context)
63
IType type = typeReference.Resolve(context);
64
IEnumerable<IMember> members;
65
if (entityType == EntityType.Method) {
66
members = type.GetMethods(
67
m => m.Name == name && m.EntityType == EntityType.Method
68
&& m.TypeParameters.Count == typeParameterCount && !m.IsExplicitInterfaceImplementation,
69
GetMemberOptions.IgnoreInheritedMembers);
71
members = type.GetMembers(
72
m => m.Name == name && m.EntityType == entityType && !m.IsExplicitInterfaceImplementation,
73
GetMemberOptions.IgnoreInheritedMembers);
75
var resolvedParameterTypes = parameterTypes.Resolve(context);
76
foreach (IMember member in members) {
77
IParameterizedMember parameterizedMember = member as IParameterizedMember;
78
if (parameterizedMember == null) {
79
if (parameterTypes.Count == 0)
81
} else if (parameterTypes.Count == parameterizedMember.Parameters.Count) {
82
bool signatureMatches = true;
83
for (int i = 0; i < parameterTypes.Count; i++) {
84
IType type1 = DummyTypeParameter.NormalizeAllTypeParameters(resolvedParameterTypes[i]);
85
IType type2 = DummyTypeParameter.NormalizeAllTypeParameters(parameterizedMember.Parameters[i].Type);
86
if (!type1.Equals(type2)) {
87
signatureMatches = false;
98
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
100
typeReference = provider.Intern(typeReference);
101
name = provider.Intern(name);
102
parameterTypes = provider.InternList(parameterTypes);
105
int ISupportsInterning.GetHashCodeForInterning()
107
return (int)entityType ^ typeReference.GetHashCode() ^ name.GetHashCode() ^ parameterTypes.GetHashCode();
110
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
112
DefaultMemberReference o = other as DefaultMemberReference;
113
return o != null && entityType == o.entityType && typeReference == o.typeReference && name == o.name && parameterTypes == o.parameterTypes;