Browse Source

Fixed GetDelegateInvokeMethod() for parameterized types.

Fixed copy constructor of DefaultMethod.
Fixed handling of "class" constraint in CecilLoader.
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
97d096414b
  1. 2
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  2. 31
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  3. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  4. 2
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  5. 12
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  6. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs
  7. 9
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
  8. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs
  9. 31
      ICSharpCode.NRefactory/TypeSystem/Implementation/SubstitutionTypeReference.cs
  10. 31
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

2
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs

@ -10,6 +10,8 @@ using System.Runtime.InteropServices; @@ -10,6 +10,8 @@ using System.Runtime.InteropServices;
namespace ICSharpCode.NRefactory.TypeSystem.TestCase
{
public delegate S GenericDelegate<in T, out S>(T input) where T : S where S : class;
public class SimplePublicClass
{
public void Method() {}

31
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -363,5 +363,36 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -363,5 +363,36 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual(0, p.Attributes.Count);
Assert.IsTrue(p.Type is ArrayTypeReference);
}
[Test, Ignore("C# Parser does not set the variance")]
public void GenericDelegate_Variance()
{
ITypeDefinition type = ctx.GetTypeDefinition(typeof(GenericDelegate<,>));
Assert.AreEqual(VarianceModifier.Contravariant, type.TypeParameters[0].Variance);
Assert.AreEqual(VarianceModifier.Covariant, type.TypeParameters[1].Variance);
Assert.AreSame(type.TypeParameters[1], type.TypeParameters[0].Constraints[0]);
}
[Test]
public void GenericDelegate_ReferenceTypeConstraints()
{
ITypeDefinition type = ctx.GetTypeDefinition(typeof(GenericDelegate<,>));
Assert.IsFalse(type.TypeParameters[0].HasReferenceTypeConstraint);
Assert.IsTrue(type.TypeParameters[1].HasReferenceTypeConstraint);
Assert.IsTrue(type.TypeParameters[0].IsReferenceType(ctx) == true);
Assert.IsTrue(type.TypeParameters[1].IsReferenceType(ctx) == true);
}
[Test]
public void GenericDelegate_GetInvokeMethod()
{
IType type = typeof(GenericDelegate<string, object>).ToTypeReference().Resolve(ctx);
IMethod m = type.GetDelegateInvokeMethod();
Assert.AreEqual("Invoke", m.Name);
Assert.AreEqual("System.Object", m.ReturnType.Resolve(ctx).FullName);
Assert.AreEqual("System.String", m.Parameters[0].Type.Resolve(ctx).FullName);
}
}
}

3
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</ProjectGuid>
@ -248,6 +248,7 @@ @@ -248,6 +248,7 @@
<Compile Include="TypeSystem\Implementation\SpecializedField.cs" />
<Compile Include="TypeSystem\Implementation\SpecializedMethod.cs" />
<Compile Include="TypeSystem\Implementation\SpecializedProperty.cs" />
<Compile Include="TypeSystem\Implementation\SubstitutionTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeStorage.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />
<Compile Include="TypeSystem\Implementation\VoidTypeDefinition.cs" />

2
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -1113,7 +1113,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1113,7 +1113,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
break;
}
tp.HasDefaultConstructorConstraint = g.HasReferenceTypeConstraint;
tp.HasReferenceTypeConstraint = g.HasReferenceTypeConstraint;
tp.HasValueTypeConstraint = g.HasNotNullableValueTypeConstraint;
tp.HasDefaultConstructorConstraint = g.HasDefaultConstructorConstraint;

12
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp;
@ -187,8 +188,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -187,8 +188,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeDefinition def = type.GetDefinition();
if (def != null && def.ClassType == ClassType.Delegate) {
foreach (IMethod method in def.Methods) {
if (method.Name == "Invoke")
if (method.Name == "Invoke") {
ParameterizedType pt = type as ParameterizedType;
if (pt != null) {
SpecializedMethod m = new SpecializedMethod(method);
m.SetDeclaringType(pt);
var substitution = pt.GetSubstitution();
m.SubstituteTypes(t => new SubstitutionTypeReference(t, substitution));
return m;
}
return method;
}
}
}
return null;

6
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs

@ -36,9 +36,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -36,9 +36,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// </summary>
protected DefaultMethod(IMethod method) : base(method)
{
returnTypeAttributes = CopyList(returnTypeAttributes);
typeParameters = CopyList(typeParameters);
parameters = CopyList(parameters);
returnTypeAttributes = CopyList(method.ReturnTypeAttributes);
typeParameters = CopyList(method.TypeParameters);
parameters = CopyList(method.Parameters);
this.IsExtensionMethod = method.IsExtensionMethod;
}

9
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs

@ -52,20 +52,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -52,20 +52,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return false;
return object.Equals(this.memberDefinition, other.memberDefinition) && object.Equals(this.declaringType, other.declaringType);
}
/// <summary>
/// Performs type substitution in parameter types and in the return type.
/// </summary>
public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution)
public void SubstituteTypes(Func<ITypeReference, ITypeReference> substitution)
{
this.ReturnType = this.ReturnType.Resolve(context).AcceptVisitor(substitution);
this.ReturnType = substitution(this.ReturnType);
var p = this.Parameters;
for (int i = 0; i < p.Count; i++) {
IType newType = p[i].Type.Resolve(context).AcceptVisitor(substitution);
ITypeReference newType = substitution(p[i].Type);
if (newType != p[i].Type) {
p[i] = new DefaultParameter(p[i]) { Type = newType };
}
}
// TODO: we might also have to perform substitution within the method's constraints
}
}
}

6
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs

@ -56,12 +56,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -56,12 +56,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// <summary>
/// Performs type substitution in parameter types and in the return type.
/// </summary>
public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution)
public void SubstituteTypes(Func<ITypeReference, ITypeReference> substitution)
{
this.ReturnType = this.ReturnType.Resolve(context).AcceptVisitor(substitution);
this.ReturnType = substitution(this.ReturnType);
var p = this.Parameters;
for (int i = 0; i < p.Count; i++) {
IType newType = p[i].Type.Resolve(context).AcceptVisitor(substitution);
ITypeReference newType = substitution(p[i].Type);
if (newType != p[i].Type) {
p[i] = new DefaultParameter(p[i]) { Type = newType };
}

31
ICSharpCode.NRefactory/TypeSystem/Implementation/SubstitutionTypeReference.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT license (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// A type reference that wraps another type reference; but performs a substitution in the resolved type.
/// </summary>
public class SubstitutionTypeReference : ITypeReference
{
readonly ITypeReference baseTypeReference;
readonly TypeVisitor substitution;
public SubstitutionTypeReference(ITypeReference baseTypeReference, TypeVisitor substitution)
{
if (baseTypeReference == null)
throw new ArgumentNullException("baseTypeReference");
if (substitution == null)
throw new ArgumentNullException("substitution");
this.baseTypeReference = baseTypeReference;
this.substitution = substitution;
}
public IType Resolve(ITypeResolveContext context)
{
return baseTypeReference.Resolve(context).AcceptVisitor(substitution);
}
}
}

31
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -157,6 +157,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -157,6 +157,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
return type.AcceptVisitor(new Substitution(typeArguments));
}
/// <summary>
/// Gets a type visitor that performs the substitution of class type parameters with the type arguments
/// of this parameterized type.
/// </summary>
public TypeVisitor GetSubstitution()
{
return new Substitution(typeArguments);
}
public IEnumerable<IType> GetBaseTypes(ITypeResolveContext context)
{
Substitution substitution = new Substitution(typeArguments);
@ -200,11 +209,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -200,11 +209,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMethod> methods = genericType.GetMethods(context, filter).ToList();
for (int i = 0; i < methods.Count; i++) {
SpecializedMethod m = new SpecializedMethod(methods[i]);
m.SetDeclaringType(this);
m.SubstituteTypes(context, substitution);
m.SubstituteTypes(substitutionFunc);
methods[i] = m;
}
return methods;
@ -213,11 +223,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -213,11 +223,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMethod> methods = genericType.GetConstructors(context, filter).ToList();
for (int i = 0; i < methods.Count; i++) {
SpecializedMethod m = new SpecializedMethod(methods[i]);
m.SetDeclaringType(this);
m.SubstituteTypes(context, substitution);
m.SubstituteTypes(substitutionFunc);
methods[i] = m;
}
return methods;
@ -226,11 +237,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -226,11 +237,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IProperty> properties = genericType.GetProperties(context, filter).ToList();
for (int i = 0; i < properties.Count; i++) {
SpecializedProperty p = new SpecializedProperty(properties[i]);
p.SetDeclaringType(this);
p.SubstituteTypes(context, substitution);
p.SubstituteTypes(substitutionFunc);
properties[i] = p;
}
return properties;
@ -265,41 +277,42 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -265,41 +277,42 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMember> members = genericType.GetMembers(context, filter).ToList();
for (int i = 0; i < members.Count; i++) {
members[i] = Specialize(members[i], context, substitution);
members[i] = Specialize(members[i], substitutionFunc);
}
return members;
}
IMember Specialize(IMember member, ITypeResolveContext context, Substitution substitution)
IMember Specialize(IMember member, Func<ITypeReference, ITypeReference> substitution)
{
IMethod method = member as IMethod;
if (method != null) {
SpecializedMethod m = new SpecializedMethod(method);
m.SetDeclaringType(this);
m.SubstituteTypes(context, substitution);
m.SubstituteTypes(substitution);
return m;
}
IProperty property = member as IProperty;
if (property != null) {
SpecializedProperty p = new SpecializedProperty(property);
p.SetDeclaringType(this);
p.SubstituteTypes(context, substitution);
p.SubstituteTypes(substitution);
return p;
}
IField field = member as IField;
if (field != null) {
SpecializedField f = new SpecializedField(field);
f.SetDeclaringType(this);
f.ReturnType = f.ReturnType.Resolve(context).AcceptVisitor(substitution);
f.ReturnType = substitution(f.ReturnType);
return f;
}
IEvent ev = member as IEvent;
if (ev != null) {
SpecializedEvent e = new SpecializedEvent(ev);
e.SetDeclaringType(this);
e.ReturnType = e.ReturnType.Resolve(context).AcceptVisitor(substitution);
e.ReturnType = substitution(e.ReturnType);
return e;
}
throw new ArgumentException("Unknown member");

Loading…
Cancel
Save