Browse Source

Fixed context for determining accessibility of protected inner classes when resolving a base type reference (NameLookupTests.InheritFromProtectedInnerClassTest)

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
4fe7c72b16
  1. 6
      ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
  3. 4
      ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs
  5. 4
      ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs
  6. 2
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  7. 2
      ICSharpCode.NRefactory.CSharp/NameLookupMode.cs
  8. 6
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantNamespaceUsageIssue.cs
  9. 4
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantThisIssue.cs
  10. 90
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  11. 62
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  12. 10
      ICSharpCode.NRefactory.CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs
  13. 4
      ICSharpCode.NRefactory.CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs
  14. 8
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  15. 1
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  16. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

6
ICSharpCode.NRefactory.CSharp/Ast/AstType.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
return SpecialType.UnknownType;
}
@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitPatternPlaceholder (this, child, data);
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
throw new NotSupportedException();
}
@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
/// (on CSharpTypeResolveContext only) is used.
/// </remarks>
public abstract ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type);
public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type);
/// <summary>
/// Creates a pointer type from this type by nesting it in a <see cref="ComposedType"/>.

2
ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp
return this;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
ITypeReference t = this.BaseType.ToTypeReference(lookupMode);
if (this.HasNullableSpecifier) {

4
ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
TypeOrNamespaceReference t;
if (this.IsDoubleColon) {
@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (var ta in this.TypeArguments) {
typeArguments.Add(ta.ToTypeReference(lookupMode));
}
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments);
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments, lookupMode);
}
}
}

2
ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp
return Keyword;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword);
if (typeCode == KnownTypeCode.None)

4
ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
return SpecialType.UnknownType;
}
@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
var typeArguments = new List<ITypeReference>();
foreach (var ta in this.TypeArguments) {

2
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -270,7 +270,7 @@ @@ -270,7 +270,7 @@
<Compile Include="Resolver\TypeInference.cs" />
<Compile Include="Completion\ICompletionDataFactory.cs" />
<Compile Include="Completion\IParameterCompletionDataFactory.cs" />
<Compile Include="SimpleNameLookupMode.cs" />
<Compile Include="NameLookupMode.cs" />
<Compile Include="TypeSystem\AliasNamespaceReference.cs" />
<Compile Include="TypeSystem\AttributeTypeReference.cs" />
<Compile Include="TypeSystem\ConstantValues.cs" />

2
ICSharpCode.NRefactory.CSharp/SimpleNameLookupMode.cs → ICSharpCode.NRefactory.CSharp/NameLookupMode.cs

@ -20,7 +20,7 @@ using System; @@ -20,7 +20,7 @@ using System;
namespace ICSharpCode.NRefactory.CSharp
{
public enum SimpleNameLookupMode
public enum NameLookupMode
{
/// <summary>
/// Normal name lookup in expressions

6
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantNamespaceUsageIssue.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -61,7 +61,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
base.VisitMemberReferenceExpression(memberReferenceExpression);
HandleMemberReference(
memberReferenceExpression, memberReferenceExpression.Target, memberReferenceExpression.MemberNameToken, memberReferenceExpression.TypeArguments, SimpleNameLookupMode.Expression,
memberReferenceExpression, memberReferenceExpression.Target, memberReferenceExpression.MemberNameToken, memberReferenceExpression.TypeArguments, NameLookupMode.Expression,
script => {
script.Replace(memberReferenceExpression, RefactoringAstHelper.RemoveTarget(memberReferenceExpression));
});
@ -71,13 +71,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -71,13 +71,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
base.VisitMemberType(memberType);
HandleMemberReference(
memberType, memberType.Target, memberType.MemberNameToken, memberType.TypeArguments, SimpleNameLookupMode.Type,
memberType, memberType.Target, memberType.MemberNameToken, memberType.TypeArguments, NameLookupMode.Type,
script => {
script.Replace(memberType, RefactoringAstHelper.RemoveTarget(memberType));
});
}
void HandleMemberReference(AstNode wholeNode, AstNode targetNode, Identifier memberName, IEnumerable<AstType> typeArguments, SimpleNameLookupMode mode, Action<Script> action)
void HandleMemberReference(AstNode wholeNode, AstNode targetNode, Identifier memberName, IEnumerable<AstType> typeArguments, NameLookupMode mode, Action<Script> action)
{
var result = ctx.Resolve(targetNode);
if (!(result is NamespaceResolveResult)) {

4
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantThisIssue.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// RedundantThisInspector.cs
//
// Author:
@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return;
}
var result = state.LookupSimpleNameOrTypeName(memberReference.MemberName, EmptyList<IType>.Instance, SimpleNameLookupMode.Expression);
var result = state.LookupSimpleNameOrTypeName(memberReference.MemberName, EmptyList<IType>.Instance, NameLookupMode.Expression);
bool isRedundant;
if (result is MemberResolveResult) {

90
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -371,7 +371,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -371,7 +371,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
case UnaryOperatorType.AddressOf:
return UnaryOperatorResolveResult(new PointerType(expression.Type), op, expression);
case UnaryOperatorType.Await:
ResolveResult getAwaiterMethodGroup = ResolveMemberAccess(expression, "GetAwaiter", EmptyList<IType>.Instance, true);
ResolveResult getAwaiterMethodGroup = ResolveMemberAccess(expression, "GetAwaiter", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
ResolveResult getAwaiterInvocation = ResolveInvocation(getAwaiterMethodGroup, new ResolveResult[0]);
var getResultMethodGroup = CreateMemberLookup().Lookup(getAwaiterInvocation, "GetResult", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
if (getResultMethodGroup != null) {
@ -1315,10 +1315,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1315,10 +1315,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return LookupSimpleNameOrTypeName(
identifier, typeArguments,
isInvocationTarget ? SimpleNameLookupMode.InvocationTarget : SimpleNameLookupMode.Expression);
isInvocationTarget ? NameLookupMode.InvocationTarget : NameLookupMode.Expression);
}
public ResolveResult LookupSimpleNameOrTypeName(string identifier, IList<IType> typeArguments, SimpleNameLookupMode lookupMode)
public ResolveResult LookupSimpleNameOrTypeName(string identifier, IList<IType> typeArguments, NameLookupMode lookupMode)
{
// C# 4.0 spec: §3.8 Namespace and type names; §7.6.2 Simple Names
@ -1330,7 +1330,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1330,7 +1330,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
int k = typeArguments.Count;
if (k == 0) {
if (lookupMode == SimpleNameLookupMode.Expression || lookupMode == SimpleNameLookupMode.InvocationTarget) {
if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget) {
// Look in local variables
foreach (IVariable v in this.LocalVariables) {
if (v.Name == identifier) {
@ -1366,13 +1366,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1366,13 +1366,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
bool foundInCache = false;
if (k == 0) {
switch (lookupMode) {
case SimpleNameLookupMode.Expression:
case NameLookupMode.Expression:
cache = currentTypeDefinitionCache.SimpleNameLookupCacheExpression;
break;
case SimpleNameLookupMode.InvocationTarget:
case NameLookupMode.InvocationTarget:
cache = currentTypeDefinitionCache.SimpleNameLookupCacheInvocationTarget;
break;
case SimpleNameLookupMode.Type:
case NameLookupMode.Type:
cache = currentTypeDefinitionCache.SimpleTypeLookupCache;
break;
}
@ -1397,13 +1397,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1397,13 +1397,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// If no using scope was specified, we still need to look in the global namespace:
r = LookInUsingScopeNamespace(null, compilation.RootNamespace, identifier, typeArguments, parameterizeResultType);
} else {
if (k == 0 && lookupMode != SimpleNameLookupMode.TypeInUsingDeclaration) {
if (k == 0 && lookupMode != NameLookupMode.TypeInUsingDeclaration) {
if (!context.CurrentUsingScope.ResolveCache.TryGetValue(identifier, out r)) {
r = LookInCurrentUsingScope(identifier, typeArguments, false, false);
r = context.CurrentUsingScope.ResolveCache.GetOrAdd(identifier, r);
}
} else {
r = LookInCurrentUsingScope(identifier, typeArguments, lookupMode == SimpleNameLookupMode.TypeInUsingDeclaration, parameterizeResultType);
r = LookInCurrentUsingScope(identifier, typeArguments, lookupMode == NameLookupMode.TypeInUsingDeclaration, parameterizeResultType);
}
}
if (r != null)
@ -1422,23 +1422,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1422,23 +1422,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
trr = null;
return false;
}
trr = LookupSimpleNameOrTypeName (identifier, EmptyList<IType>.Instance, SimpleNameLookupMode.Type) as TypeResolveResult;
trr = LookupSimpleNameOrTypeName (identifier, EmptyList<IType>.Instance, NameLookupMode.Type) as TypeResolveResult;
return trr != null && trr.Type.Equals (rr.Type);
}
ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, SimpleNameLookupMode lookupMode, bool parameterizeResultType)
ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType)
{
int k = typeArguments.Count;
MemberLookup lookup;
if (lookupMode == SimpleNameLookupMode.BaseTypeReference && this.CurrentTypeDefinition != null) {
// When looking up a base type reference, treat us as being outside the current type definition
// for accessibility purposes.
// This avoids a stack overflow when referencing a protected class nested inside the base class
// of a parent class. (NameLookupTests.InnerClassInheritingFromProtectedBaseInnerClassShouldNotCauseStackOverflow)
lookup = new MemberLookup(this.CurrentTypeDefinition.DeclaringTypeDefinition, this.Compilation.MainAssembly, false);
} else {
lookup = CreateMemberLookup();
}
MemberLookup lookup = CreateMemberLookup(lookupMode);
// look in current type definitions
for (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition) {
if (k == 0) {
@ -1452,15 +1443,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1452,15 +1443,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
if (lookupMode == SimpleNameLookupMode.BaseTypeReference && t == this.CurrentTypeDefinition) {
if (lookupMode == NameLookupMode.BaseTypeReference && t == this.CurrentTypeDefinition) {
// don't look in current type when resolving a base type reference
continue;
}
ResolveResult r;
if (lookupMode == SimpleNameLookupMode.Expression || lookupMode == SimpleNameLookupMode.InvocationTarget) {
if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget) {
var targetResolveResult = (t == this.CurrentTypeDefinition ? ResolveThisReference() : new TypeResolveResult(t));
r = lookup.Lookup(targetResolveResult, identifier, typeArguments, lookupMode == SimpleNameLookupMode.InvocationTarget);
r = lookup.Lookup(targetResolveResult, identifier, typeArguments, lookupMode == NameLookupMode.InvocationTarget);
} else {
r = lookup.LookupType(t, identifier, typeArguments, parameterizeResultType);
}
@ -1587,20 +1578,36 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1587,20 +1578,36 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region ResolveMemberAccess
public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IList<IType> typeArguments, bool isInvocationTarget = false)
public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IList<IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)
{
// C# 4.0 spec: §7.6.4
bool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
NamespaceResolveResult nrr = target as NamespaceResolveResult;
if (nrr != null) {
return ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, typeArguments.Count > 0);
return ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType);
}
if (target.Type.Kind == TypeKind.Dynamic)
return DynamicResult;
MemberLookup lookup = CreateMemberLookup();
ResolveResult result = lookup.Lookup(target, identifier, typeArguments, isInvocationTarget);
MemberLookup lookup = CreateMemberLookup(lookupMode);
ResolveResult result;
switch (lookupMode) {
case NameLookupMode.Expression:
result = lookup.Lookup(target, identifier, typeArguments, isInvocation: false);
break;
case NameLookupMode.InvocationTarget:
result = lookup.Lookup(target, identifier, typeArguments, isInvocation: true);
break;
case NameLookupMode.Type:
case NameLookupMode.TypeInUsingDeclaration:
case NameLookupMode.BaseTypeReference:
result = lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType);
break;
default:
throw new NotSupportedException("Invalid value for NameLookupMode");
}
if (result is UnknownMemberResolveResult) {
var extensionMethods = GetExtensionMethods(identifier, typeArguments);
if (extensionMethods.Count > 0) {
@ -1619,17 +1626,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1619,17 +1626,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return result;
}
[Obsolete("Use ResolveMemberAccess() with NameLookupMode.Type instead")]
public ResolveResult ResolveMemberType(ResolveResult target, string identifier, IList<IType> typeArguments)
{
bool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
NamespaceResolveResult nrr = target as NamespaceResolveResult;
if (nrr != null) {
return ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType);
}
MemberLookup lookup = CreateMemberLookup();
return lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType);
return ResolveMemberAccess(target, identifier, typeArguments, NameLookupMode.Type);
}
ResolveResult ResolveMemberAccessOnNamespace(NamespaceResolveResult nrr, string identifier, IList<IType> typeArguments, bool parameterizeResultType)
@ -1659,6 +1659,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1659,6 +1659,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
&& currentTypeDefinition != null && currentTypeDefinition.Kind == TypeKind.Enum;
return new MemberLookup(currentTypeDefinition, this.Compilation.MainAssembly, isInEnumMemberInitializer);
}
/// <summary>
/// Creates a MemberLookup instance using this resolver's settings.
/// </summary>
public MemberLookup CreateMemberLookup(NameLookupMode lookupMode)
{
if (lookupMode == NameLookupMode.BaseTypeReference && this.CurrentTypeDefinition != null) {
// When looking up a base type reference, treat us as being outside the current type definition
// for accessibility purposes.
// This avoids a stack overflow when referencing a protected class nested inside the base class
// of a parent class. (NameLookupTests.InnerClassInheritingFromProtectedBaseInnerClassShouldNotCauseStackOverflow)
return new MemberLookup(this.CurrentTypeDefinition.DeclaringTypeDefinition, this.Compilation.MainAssembly, false);
} else {
return CreateMemberLookup();
}
}
#endregion
#region ResolveIdentifierInObjectInitializer

62
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -1403,7 +1403,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1403,7 +1403,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
return resolver.ResolveMemberAccess(deferencedTarget, pointerReferenceExpression.MemberName,
typeArguments,
IsTargetOfInvocation(pointerReferenceExpression));
GetNameLookupMode(pointerReferenceExpression));
} else {
ScanChildren(pointerReferenceExpression);
return null;
@ -1545,12 +1545,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1545,12 +1545,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return arguments;
}
static bool IsTargetOfInvocation(AstNode node)
static NameLookupMode GetNameLookupMode(Expression expr)
{
InvocationExpression ie = node.Parent as InvocationExpression;
return ie != null && ie.Target == node;
InvocationExpression ie = expr.Parent as InvocationExpression;
if (ie != null && ie.Target == expr)
return NameLookupMode.InvocationTarget;
else
return NameLookupMode.Expression;
}
/// <summary>
/// Gets whether 'rr' is considered a static access on the target identifier.
@ -1571,8 +1573,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1571,8 +1573,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// simple names and type names might occur.
if (resolverEnabled) {
var typeArguments = ResolveTypeArguments(identifierExpression.TypeArguments);
return resolver.ResolveSimpleName(identifierExpression.Identifier, typeArguments,
IsTargetOfInvocation(identifierExpression));
var lookupMode = GetNameLookupMode(identifierExpression);
return resolver.LookupSimpleNameOrTypeName(
identifierExpression.Identifier, typeArguments, lookupMode);
} else {
ScanChildren(identifierExpression);
return null;
@ -1621,7 +1624,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1621,7 +1624,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var typeArguments = ResolveTypeArguments(memberReferenceExpression.TypeArguments);
return resolver.ResolveMemberAccess(
target, memberReferenceExpression.MemberName, typeArguments,
IsTargetOfInvocation(memberReferenceExpression));
GetNameLookupMode(memberReferenceExpression));
}
ResolveResult IAstVisitor<ResolveResult>.VisitInvocationExpression(InvocationExpression invocationExpression)
@ -2489,7 +2492,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2489,7 +2492,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
elementType = isImplicitlyTypedVariable ? SpecialType.Dynamic : compilation.FindType(KnownTypeCode.Object);
}
getEnumeratorInvocation = resolver.ResolveCast(collectionType, expression);
getEnumeratorInvocation = resolver.ResolveMemberAccess(getEnumeratorInvocation, "GetEnumerator", EmptyList<IType>.Instance, true);
getEnumeratorInvocation = resolver.ResolveMemberAccess(getEnumeratorInvocation, "GetEnumerator", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
getEnumeratorInvocation = resolver.ResolveInvocation(getEnumeratorInvocation, new ResolveResult[0]);
} else {
var getEnumeratorMethodGroup = memberLookup.Lookup(expression, "GetEnumerator", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
@ -2569,7 +2572,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2569,7 +2572,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
enumeratorType = SpecialType.UnknownType;
}
getEnumeratorInvocation = resolver.ResolveCast(collectionType, expression);
getEnumeratorInvocation = resolver.ResolveMemberAccess(getEnumeratorInvocation, "GetEnumerator", EmptyList<IType>.Instance, true);
getEnumeratorInvocation = resolver.ResolveMemberAccess(getEnumeratorInvocation, "GetEnumerator", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
getEnumeratorInvocation = resolver.ResolveInvocation(getEnumeratorInvocation, new ResolveResult[0]);
}
#endregion
@ -3010,15 +3013,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3010,15 +3013,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
// Figure out the correct lookup mode:
AstType outermostType = simpleType;
while (outermostType.Parent is AstType)
outermostType = (AstType)outermostType.Parent;
SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type;
if (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration) {
lookupMode = SimpleNameLookupMode.TypeInUsingDeclaration;
} else if (outermostType.Parent is TypeDeclaration && outermostType.Role == Roles.BaseType) {
lookupMode = SimpleNameLookupMode.BaseTypeReference;
}
NameLookupMode lookupMode = GetNameLookupMode(simpleType);
var typeArguments = ResolveTypeArguments(simpleType.TypeArguments);
Identifier identifier = simpleType.IdentifierToken;
@ -3033,6 +3028,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3033,6 +3028,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return rr;
}
NameLookupMode GetNameLookupMode(AstType type)
{
AstType outermostType = type;
while (outermostType.Parent is AstType)
outermostType = (AstType)outermostType.Parent;
NameLookupMode lookupMode = NameLookupMode.Type;
if (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration) {
lookupMode = NameLookupMode.TypeInUsingDeclaration;
} else if (outermostType.Parent is TypeDeclaration && outermostType.Role == Roles.BaseType) {
lookupMode = NameLookupMode.BaseTypeReference;
}
return lookupMode;
}
ResolveResult IAstVisitor<ResolveResult>.VisitMemberType(MemberType memberType)
{
ResolveResult target;
@ -3049,11 +3058,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3049,11 +3058,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
target = Resolve(memberType.Target);
}
NameLookupMode lookupMode = GetNameLookupMode(memberType);
var typeArguments = ResolveTypeArguments(memberType.TypeArguments);
Identifier identifier = memberType.MemberNameToken;
ResolveResult rr = resolver.ResolveMemberType(target, identifier.Name, typeArguments);
ResolveResult rr = resolver.ResolveMemberAccess(target, identifier.Name, typeArguments, lookupMode);
if (memberType.Parent is Attribute && !identifier.IsVerbatim) {
var withSuffix = resolver.ResolveMemberType(target, identifier.Name + "Attribute", typeArguments);
var withSuffix = resolver.ResolveMemberAccess(target, identifier.Name + "Attribute", typeArguments, lookupMode);
if (AttributeTypeReference.PreferAttributeTypeWithSuffix(rr.Type, withSuffix.Type, resolver.Compilation))
return withSuffix;
}
@ -3225,7 +3235,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3225,7 +3235,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
v = MakeVariable(ResolveType(queryFromClause.Type), queryFromClause.IdentifierToken);
// resolve the .Cast<>() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { v.Type }, true);
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { v.Type }, NameLookupMode.InvocationTarget);
result = resolver.ResolveInvocation(methodGroup, new ResolveResult[0]);
}
@ -3244,7 +3254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3244,7 +3254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// from .. from ... ... - introduce a transparent identifier
selectResult = MakeTransparentIdentifierResolveResult();
}
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "SelectMany", EmptyList<IType>.Instance, true);
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "SelectMany", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
ResolveResult[] arguments = {
new QueryExpressionLambda(1, result),
new QueryExpressionLambda(2, selectResult)
@ -3287,7 +3297,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3287,7 +3297,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v));
if (currentQueryResult != null) {
// resolve the .Select() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList<IType>.Instance, true);
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
ResolveResult[] arguments = { new QueryExpressionLambda(1, MakeTransparentIdentifierResolveResult()) };
return resolver.ResolveInvocation(methodGroup, arguments);
} else {
@ -3308,7 +3318,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3308,7 +3318,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
variableType = ResolveType(queryJoinClause.Type);
// resolve the .Cast<>() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { variableType }, true);
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { variableType }, NameLookupMode.InvocationTarget);
inResult = resolver.ResolveInvocation(methodGroup, new ResolveResult[0]);
}

10
ICSharpCode.NRefactory.CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs

@ -35,8 +35,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -35,8 +35,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
TypeOrNamespaceReference target;
string identifier;
IList<ITypeReference> typeArguments;
readonly NameLookupMode lookupMode;
public MemberTypeOrNamespaceReference(TypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments)
public MemberTypeOrNamespaceReference(TypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
{
if (target == null)
throw new ArgumentNullException("target");
@ -45,6 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -45,6 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
this.target = target;
this.identifier = identifier;
this.typeArguments = typeArguments ?? EmptyList<ITypeReference>.Instance;
this.lookupMode = lookupMode;
}
public string Identifier {
@ -76,7 +78,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -76,7 +78,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
return resolver.ResolveMemberType(targetRR, identifier, typeArgs);
return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
} else {
// This can happen for "class Test : $Test.Base$ { public class Base {} }":
return ErrorResolveResult.UnknownError; // don't cache this error
@ -106,6 +108,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -106,6 +108,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
hashCode += 1000000007 * target.GetHashCode();
hashCode += 1000000033 * identifier.GetHashCode();
hashCode += 1000000087 * typeArguments.GetHashCode();
hashCode += 1000000021 * (int)lookupMode;
}
return hashCode;
}
@ -114,7 +117,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -114,7 +117,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
MemberTypeOrNamespaceReference o = other as MemberTypeOrNamespaceReference;
return o != null && this.target == o.target
&& this.identifier == o.identifier && this.typeArguments == o.typeArguments;
&& this.identifier == o.identifier && this.typeArguments == o.typeArguments
&& this.lookupMode == o.lookupMode;
}
}
}

4
ICSharpCode.NRefactory.CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs

@ -35,9 +35,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -35,9 +35,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
string identifier;
IList<ITypeReference> typeArguments;
readonly SimpleNameLookupMode lookupMode;
readonly NameLookupMode lookupMode;
public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> typeArguments, SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
{
if (identifier == null)
throw new ArgumentNullException("identifier");

8
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -129,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override IUnresolvedEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration)
{
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(SimpleNameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (u != null) {
if (interningProvider != null)
u = interningProvider.Intern(u);
@ -140,7 +140,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -140,7 +140,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override IUnresolvedEntity VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
{
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(SimpleNameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (u != null) {
if (interningProvider != null)
u = interningProvider.Intern(u);
@ -211,7 +211,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -211,7 +211,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints, EntityType.TypeDefinition);
foreach (AstType baseType in typeDeclaration.BaseTypes) {
td.BaseTypes.Add(baseType.ToTypeReference(SimpleNameLookupMode.BaseTypeReference));
td.BaseTypes.Add(baseType.ToTypeReference(NameLookupMode.BaseTypeReference));
}
foreach (EntityDeclaration member in typeDeclaration.Members) {
@ -918,7 +918,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -918,7 +918,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
#region Types
[Obsolete("Use AstType.ToTypeReference() instead.")]
public static ITypeReference ConvertType(AstType type, SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public static ITypeReference ConvertType(AstType type, NameLookupMode lookupMode = NameLookupMode.Type)
{
return type.ToTypeReference(lookupMode);
}

1
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -967,6 +967,7 @@ class MainClass : Test @@ -967,6 +967,7 @@ class MainClass : Test
}
";
var result = Resolve<MemberResolveResult>(program);
Assert.IsFalse(result.IsError);
Assert.AreEqual("Test.Foo.Bar", result.Member.FullName);
}
}

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
protected static TypeOrNamespaceReference MakeReference(string namespaceName)
{
string[] nameParts = namespaceName.Split('.');
TypeOrNamespaceReference r = new SimpleTypeOrNamespaceReference(nameParts[0], new ITypeReference[0], SimpleNameLookupMode.TypeInUsingDeclaration);
TypeOrNamespaceReference r = new SimpleTypeOrNamespaceReference(nameParts[0], new ITypeReference[0], NameLookupMode.TypeInUsingDeclaration);
for (int i = 1; i < nameParts.Length; i++) {
r = new MemberTypeOrNamespaceReference(r, nameParts[i], new ITypeReference[0]);
}

Loading…
Cancel
Save