Browse Source

Avoid looking for inner classes when resolving a class constraint.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
31474555b2
  1. 15
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  2. 3
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  3. 50
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  4. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/BaseTypeCollector.cs

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

@ -3257,13 +3257,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstType outermostType = type; AstType outermostType = type;
while (outermostType.Parent is AstType) while (outermostType.Parent is AstType)
outermostType = (AstType)outermostType.Parent; outermostType = (AstType)outermostType.Parent;
NameLookupMode lookupMode = NameLookupMode.Type;
if (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration) { if (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration) {
lookupMode = NameLookupMode.TypeInUsingDeclaration; return NameLookupMode.TypeInUsingDeclaration;
} else if (outermostType.Parent is TypeDeclaration && outermostType.Role == Roles.BaseType) { } else if (outermostType.Role == Roles.BaseType) {
lookupMode = NameLookupMode.BaseTypeReference; // Use BaseTypeReference for a type's base type, and for a constraint on a type.
} // Do not use it for a constraint on a method.
return lookupMode; if (outermostType.Parent is TypeDeclaration || (outermostType.Parent is Constraint && outermostType.Parent.Parent is TypeDeclaration))
return NameLookupMode.BaseTypeReference;
}
return NameLookupMode.Type;
} }
ResolveResult IAstVisitor<ResolveResult>.VisitMemberType(MemberType memberType) ResolveResult IAstVisitor<ResolveResult>.VisitMemberType(MemberType memberType)

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

@ -515,7 +515,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
continue; continue;
} }
} }
tp.Constraints.Add(type.ToTypeReference()); var lookupMode = (ownerType == EntityType.TypeDefinition) ? NameLookupMode.BaseTypeReference : NameLookupMode.Type;
tp.Constraints.Add(type.ToTypeReference(lookupMode));
} }
break; break;
} }

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

@ -1015,5 +1015,55 @@ namespace foo {
Assert.AreEqual("foo.Foo", result.Type.FullName); Assert.AreEqual("foo.Foo", result.Type.FullName);
} }
[Test]
public void BaseTypeReference_refers_to_outer_type()
{
string program = @"class B {}
class A : $B$ {
class B {}
}";
var result = Resolve<TypeResolveResult>(program);
Assert.IsFalse(result.IsError);
Assert.AreEqual("B", result.Type.FullName);
// also check if the reference in the type system is correct
var a = ((ITypeDefinition)result.Type).Compilation.RootNamespace.GetTypeDefinition("A", 0);
Assert.AreEqual("B", a.DirectBaseTypes.Single().FullName);
}
[Test]
public void Class_constraint_refers_to_outer_type()
{
string program = @"class B {}
class A<T> where T : $B$ {
class B {}
}";
var result = Resolve<TypeResolveResult>(program);
Assert.IsFalse(result.IsError);
Assert.AreEqual("B", result.Type.FullName);
// also check if the reference in the type system is correct
var a = ((ITypeDefinition)result.Type).Compilation.RootNamespace.GetTypeDefinition("A", 1);
Assert.AreEqual("B", a.TypeParameters.Single().DirectBaseTypes.Single().FullName);
}
[Test]
public void Method_constraint_refers_to_inner_type()
{
string program = @"class B {}
class A {
void M<T>() where T : $B$ {}
class B {}
}";
var result = Resolve<TypeResolveResult>(program);
Assert.IsFalse(result.IsError);
Assert.AreEqual("A.B", result.Type.FullName);
// also check if the reference in the type system is correct
var a = ((ITypeDefinition)result.Type).Compilation.RootNamespace.GetTypeDefinition("A", 0);
var method = a.Methods.Single(m => m.Name == "M");
Assert.AreEqual("A.B", method.TypeParameters.Single().DirectBaseTypes.Single().FullName);
}
} }
} }

2
ICSharpCode.NRefactory/TypeSystem/Implementation/BaseTypeCollector.cs

@ -55,8 +55,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
// (e.g. C implements I1 and I2, and both interfaces derive from Object) // (e.g. C implements I1 and I2, and both interfaces derive from Object)
if (!this.Contains(type)) { if (!this.Contains(type)) {
foreach (IType baseType in type.DirectBaseTypes) { foreach (IType baseType in type.DirectBaseTypes) {
if (type.Kind != TypeKind.TypeParameter && baseType.Kind == TypeKind.TypeParameter)
continue;
if (SkipImplementedInterfaces && def != null && def.Kind != TypeKind.Interface && def.Kind != TypeKind.TypeParameter) { if (SkipImplementedInterfaces && def != null && def.Kind != TypeKind.Interface && def.Kind != TypeKind.TypeParameter) {
if (baseType.Kind == TypeKind.Interface) { if (baseType.Kind == TypeKind.Interface) {
// skip the interface // skip the interface

Loading…
Cancel
Save