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;
21
using System.Collections.ObjectModel;
22
using ICSharpCode.NRefactory.CSharp.Resolver;
23
using ICSharpCode.NRefactory.Semantics;
24
using ICSharpCode.NRefactory.TypeSystem;
25
using ICSharpCode.NRefactory.Utils;
27
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
30
/// Reference to a qualified type or namespace name.
33
public sealed class MemberTypeOrNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
35
TypeOrNamespaceReference target;
37
IList<ITypeReference> typeArguments;
38
readonly NameLookupMode lookupMode;
40
public MemberTypeOrNamespaceReference(TypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
43
throw new ArgumentNullException("target");
44
if (identifier == null)
45
throw new ArgumentNullException("identifier");
47
this.identifier = identifier;
48
this.typeArguments = typeArguments ?? EmptyList<ITypeReference>.Instance;
49
this.lookupMode = lookupMode;
52
public string Identifier {
53
get { return identifier; }
56
public TypeOrNamespaceReference Target {
57
get { return target; }
60
public IList<ITypeReference> TypeArguments {
61
get { return new ReadOnlyCollection<ITypeReference>(typeArguments); }
65
/// Adds a suffix to the identifier.
66
/// Does not modify the existing type reference, but returns a new one.
68
public MemberTypeOrNamespaceReference AddSuffix(string suffix)
70
return new MemberTypeOrNamespaceReference(target, identifier + suffix, typeArguments);
73
public override ResolveResult Resolve(CSharpResolver resolver)
75
ResolveResult targetRR = target.Resolve(resolver);
78
IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
79
using (var busyLock = BusyManager.Enter(this)) {
80
if (busyLock.Success) {
81
return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
83
// This can happen for "class Test : $Test.Base$ { public class Base {} }":
84
return ErrorResolveResult.UnknownError; // don't cache this error
89
public override string ToString()
91
if (typeArguments.Count == 0)
92
return target.ToString() + "." + identifier;
94
return target.ToString() + "." + identifier + "<" + string.Join(",", typeArguments) + ">";
97
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
99
target = provider.Intern(target);
100
identifier = provider.Intern(identifier);
101
typeArguments = provider.InternList(typeArguments);
104
int ISupportsInterning.GetHashCodeForInterning()
108
hashCode += 1000000007 * target.GetHashCode();
109
hashCode += 1000000033 * identifier.GetHashCode();
110
hashCode += 1000000087 * typeArguments.GetHashCode();
111
hashCode += 1000000021 * (int)lookupMode;
116
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
118
MemberTypeOrNamespaceReference o = other as MemberTypeOrNamespaceReference;
119
return o != null && this.target == o.target
120
&& this.identifier == o.identifier && this.typeArguments == o.typeArguments
121
&& this.lookupMode == o.lookupMode;