Browse Source

ICompilation.Import(IType): added support for importing open generic types

Renamed 'IResolved' to 'ICompilationProvider'.
newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
b37698b39b
  1. 2
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs
  3. 35
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeParameterTests.cs
  4. 2
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs
  5. 45
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  6. 3
      ICSharpCode.NRefactory/TypeSystem/FullTypeName.cs
  7. 2
      ICSharpCode.NRefactory/TypeSystem/IAssembly.cs
  8. 2
      ICSharpCode.NRefactory/TypeSystem/ICompilation.cs
  9. 2
      ICSharpCode.NRefactory/TypeSystem/IEntity.cs
  10. 2
      ICSharpCode.NRefactory/TypeSystem/INamespace.cs
  11. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  12. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAttribute.cs
  13. 2
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

2
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs

@ -289,7 +289,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -289,7 +289,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
ICompilation IResolved.Compilation {
ICompilation ICompilationProvider.Compilation {
get { return assembly.Compilation; }
}

2
ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs

@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
get { return EmptyList<IAssembly>.Instance; }
}
ICompilation IResolved.Compilation {
ICompilation ICompilationProvider.Compilation {
get { return parentNamespace.Compilation; }
}

35
ICSharpCode.NRefactory.Tests/TypeSystem/TypeParameterTests.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
@ -79,5 +80,39 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -79,5 +80,39 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual("System.Collections.Generic.List`1[[System.String]]", resolvedC.TypeParameters[0].EffectiveBaseClass.ReflectionName);
Assert.AreEqual("System.Collections.Generic.List`1[[System.String]]", resolvedC.TypeParameters[1].EffectiveBaseClass.ReflectionName);
}
[Test]
public void ImportOpenGenericType()
{
// class C<T, U> { void M<X>() {} }
var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "T"));
c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 1, "U"));
var m = new DefaultUnresolvedMethod(c, "M");
m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.Method, 0, "X"));
c.Members.Add(m);
var resolvedC1 = TypeSystemHelper.CreateCompilationAndResolve(c);
var resolvedM1 = resolvedC1.Methods.Single(method => method.Name == "M");
var resolvedC2 = TypeSystemHelper.CreateCompilationAndResolve(c);
var resolvedM2 = resolvedC2.Methods.Single(method => method.Name == "M");
// the types, methods and type parameters differ in the two compilations:
Assert.AreNotEqual(resolvedC1, resolvedC2);
Assert.AreNotEqual(resolvedM1, resolvedM2);
Assert.AreNotEqual(resolvedC1.TypeParameters[1], resolvedC2.TypeParameters[1]);
Assert.AreNotEqual(resolvedM1.TypeParameters[0], resolvedM2.TypeParameters[0]);
// C<U, X>
var pt1 = new ParameterizedType(resolvedC1, new[] { resolvedC1.TypeParameters[1], resolvedM1.TypeParameters[0] });
var pt2 = (ParameterizedType)resolvedC2.Compilation.Import(pt1);
// importing resulted in C<U, X> in the new compilation:
Assert.AreEqual(resolvedC2, pt2.GetDefinition());
Assert.AreEqual(resolvedC2.TypeParameters[1], pt2.TypeArguments[0]);
Assert.AreEqual(resolvedM2.TypeParameters[0], pt2.TypeArguments[1]);
}
}
}

2
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs

@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
public static ITypeDefinition CreateCompilationAndResolve(IUnresolvedTypeDefinition unresolvedTypeDefinition)
{
var compilation = CreateCompilation(unresolvedTypeDefinition);
return unresolvedTypeDefinition.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
return compilation.MainAssembly.GetTypeDefinition(unresolvedTypeDefinition.FullTypeName);
}
}
}

45
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -96,12 +96,31 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -96,12 +96,31 @@ namespace ICSharpCode.NRefactory.TypeSystem
sealed class TypeClassificationVisitor : TypeVisitor
{
internal bool isOpen;
internal IEntity typeParameterOwner;
int typeParameterOwnerNestingLevel;
public override IType VisitTypeParameter(ITypeParameter type)
{
isOpen = true;
// If both classes and methods, or different classes (nested types)
// are involved, find the most specific one
int newNestingLevel = GetNestingLevel(type.Owner);
if (newNestingLevel > typeParameterOwnerNestingLevel) {
typeParameterOwner = type.Owner;
typeParameterOwnerNestingLevel = newNestingLevel;
}
return base.VisitTypeParameter(type);
}
static int GetNestingLevel(IEntity entity)
{
int level = 0;
while (entity != null) {
level++;
entity = entity.DeclaringTypeDefinition;
}
return level;
}
}
/// <summary>
@ -126,6 +145,21 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -126,6 +145,21 @@ namespace ICSharpCode.NRefactory.TypeSystem
return v.isOpen;
}
/// <summary>
/// Gets the entity that owns the type parameters occurring in the specified type.
/// If both class and method type parameters are present, the method is returned.
/// Returns null if the specified type is closed.
/// </summary>
/// <seealso cref="IsOpen"/>
static IEntity GetTypeParameterOwner(IType type)
{
if (type == null)
throw new ArgumentNullException("type");
TypeClassificationVisitor v = new TypeClassificationVisitor();
type.AcceptVisitor(v);
return v.typeParameterOwner;
}
/// <summary>
/// Gets whether the type is unbound (is a generic type, but no type arguments were provided).
/// </summary>
@ -162,7 +196,16 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -162,7 +196,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation");
if (type == null)
return null;
return type.ToTypeReference().Resolve(compilation.TypeResolveContext);
var compilationProvider = type as ICompilationProvider;
if (compilationProvider != null && compilationProvider.Compilation == compilation)
return type;
IEntity typeParameterOwner = GetTypeParameterOwner(type);
IEntity importedTypeParameterOwner = compilation.Import(typeParameterOwner);
if (importedTypeParameterOwner != null) {
return type.ToTypeReference().Resolve(new SimpleTypeResolveContext(importedTypeParameterOwner));
} else {
return type.ToTypeReference().Resolve(compilation.TypeResolveContext);
}
}
/// <summary>

3
ICSharpCode.NRefactory/TypeSystem/FullTypeName.cs

@ -30,7 +30,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -30,7 +30,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// A full type name can only represent type definitions, not arbitrary types.
/// It does not include any type arguments, and can not refer to array or pointer types.
///
///
/// A full type name represented as reflection name has the syntax:
/// <c>NamespaceName '.' TopLevelTypeName ['`'#] { '+' NestedTypeName ['`'#] }</c>
/// </remarks>
[Serializable]
public struct FullTypeName : IEquatable<FullTypeName>

2
ICSharpCode.NRefactory/TypeSystem/IAssembly.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -69,7 +69,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Represents an assembly.
/// </summary>
public interface IAssembly : IResolved
public interface IAssembly : ICompilationProvider
{
/// <summary>
/// Gets the original unresolved assembly.

2
ICSharpCode.NRefactory/TypeSystem/ICompilation.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
CacheManager CacheManager { get; }
}
public interface IResolved
public interface ICompilationProvider
{
ICompilation Compilation { get; }
}

2
ICSharpCode.NRefactory/TypeSystem/IEntity.cs

@ -93,7 +93,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -93,7 +93,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Represents a resolved entity.
/// </summary>
public interface IEntity : IResolved, INamedElement, IHasAccessibility
public interface IEntity : ICompilationProvider, INamedElement, IHasAccessibility
{
/// <summary>
/// Gets the entity type.

2
ICSharpCode.NRefactory/TypeSystem/INamespace.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Represents a resolved namespace.
/// </summary>
public interface INamespace : IResolved
public interface INamespace : ICompilationProvider
{
// No pointer back to unresolved namespace:
// multiple unresolved namespaces (from different assemblies) get

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

@ -429,7 +429,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -429,7 +429,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return null;
}
ICompilation IResolved.Compilation {
ICompilation ICompilationProvider.Compilation {
get { return assembly.compilation; }
}

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

@ -187,7 +187,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -187,7 +187,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return true;
}
sealed class DefaultResolvedAttribute : IAttribute, IResolved
sealed class DefaultResolvedAttribute : IAttribute, ICompilationProvider
{
readonly DefaultUnresolvedAttribute unresolved;
readonly ITypeResolveContext context;

2
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
for (int i = 0; i < this.typeArguments.Length; i++) {
if (this.typeArguments[i] == null)
throw new ArgumentNullException("typeArguments[" + i + "]");
IResolved r = this.typeArguments[i] as IResolved;
ICompilationProvider r = this.typeArguments[i] as ICompilationProvider;
if (r != null && r.Compilation != genericType.Compilation)
throw new InvalidOperationException("Cannot parameterize a type with type arguments from a different compilation.");
}

Loading…
Cancel
Save