Browse Source

Use IMember.Specialize() instead of 'new SpecializedMember()', and remove unnecessary upcasts.

pull/32/merge
Daniel Grunwald 13 years ago
parent
commit
4324311718
  1. 1
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs
  2. 5
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs
  3. 6
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Resolver/MethodGroupResolveResult.cs
  5. 15
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  6. 18
      ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs
  7. 1
      ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs
  8. 2
      ICSharpCode.NRefactory.Demo/CSDemo.cs
  9. 12
      ICSharpCode.NRefactory.Demo/MainForm.cs
  10. 1
      ICSharpCode.NRefactory.GtkDemo/MainWindow.cs
  11. 4
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs
  12. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs
  13. 4
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs
  14. 4
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs
  15. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  16. 15
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  17. 1
      ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs
  18. 2
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  19. 1
      ICSharpCode.NRefactory/Semantics/InvocationResolveResult.cs
  20. 1
      ICSharpCode.NRefactory/Semantics/ResolveResult.cs
  21. 9
      ICSharpCode.NRefactory/TypeSystem/IMember.cs
  22. 30
      ICSharpCode.NRefactory/TypeSystem/IMethod.cs
  23. 8
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  24. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs
  25. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedEvent.cs
  26. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedField.cs
  27. 32
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs
  28. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedProperty.cs
  29. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  30. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedEvent.cs
  31. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedField.cs
  32. 34
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
  33. 51
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
  34. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs
  35. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializingMemberReference.cs
  36. 3
      ICSharpCode.NRefactory/TypeSystem/InheritanceHelper.cs
  37. 2
      ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs
  38. 1
      ICSharpCode.NRefactory/TypeSystem/NullableType.cs
  39. 2
      ICSharpCode.NRefactory/TypeSystem/TypeParameterSubstitution.cs
  40. 2
      NRefactory.sln

1
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs

@ -20,7 +20,6 @@ using System;
using System.IO; using System.IO;
using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {

5
ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs

@ -234,8 +234,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
bool IMember.IsSpecialized { IMember IMember.Specialize(TypeParameterSubstitution substitution)
get { return false; } {
throw new NotSupportedException();
} }
string INamedElement.FullName { string INamedElement.FullName {

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

@ -1786,13 +1786,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (typeArguments != null && typeArguments.Count > 0) { if (typeArguments != null && typeArguments.Count > 0) {
if (method.TypeParameters.Count != typeArguments.Count) if (method.TypeParameters.Count != typeArguments.Count)
continue; continue;
SpecializedMethod sm = new SpecializedMethod(method, new TypeParameterSubstitution(null, typeArguments)); var sm = method.Specialize(new TypeParameterSubstitution(null, typeArguments));
if (IsEligibleExtensionMethod(compilation, conversions, targetType, sm, false, out inferredTypes)) if (IsEligibleExtensionMethod(compilation, conversions, targetType, sm, false, out inferredTypes))
outputGroup.Add(sm); outputGroup.Add(sm);
} else { } else {
if (IsEligibleExtensionMethod(compilation, conversions, targetType, method, true, out inferredTypes)) { if (IsEligibleExtensionMethod(compilation, conversions, targetType, method, true, out inferredTypes)) {
if (substituteInferredTypes && inferredTypes != null) { if (substituteInferredTypes && inferredTypes != null) {
outputGroup.Add(new SpecializedMethod(method, new TypeParameterSubstitution(null, inferredTypes))); outputGroup.Add(method.Specialize(new TypeParameterSubstitution(null, inferredTypes)));
} else { } else {
outputGroup.Add(method); outputGroup.Add(method);
} }
@ -1811,7 +1811,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <param name="targetType">Target type that is passed as first argument to the extension method.</param> /// <param name="targetType">Target type that is passed as first argument to the extension method.</param>
/// <param name="method">The extension method.</param> /// <param name="method">The extension method.</param>
/// <param name="useTypeInference">Whether to perform type inference for the method. /// <param name="useTypeInference">Whether to perform type inference for the method.
/// Use <c>false</c> if <paramref name="method"/> is already specialized (e.g. when type arguments were given explicitly). /// Use <c>false</c> if <paramref name="method"/> is already parameterized (e.g. when type arguments were given explicitly).
/// Otherwise, use <c>true</c>. /// Otherwise, use <c>true</c>.
/// </param> /// </param>
/// <param name="outInferredTypes">If the method is generic and <paramref name="useTypeInference"/> is <c>true</c>, /// <param name="outInferredTypes">If the method is generic and <paramref name="useTypeInference"/> is <c>true</c>,

2
ICSharpCode.NRefactory.CSharp/Resolver/MethodGroupResolveResult.cs

@ -203,7 +203,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IType[] inferredTypes; IType[] inferredTypes;
if (CSharpResolver.IsEligibleExtensionMethod(this.TargetType, method, true, out inferredTypes)) { if (CSharpResolver.IsEligibleExtensionMethod(this.TargetType, method, true, out inferredTypes)) {
if (substituteInferredTypes && inferredTypes != null) { if (substituteInferredTypes && inferredTypes != null) {
outputGroup.Add(new SpecializedMethod(method, new TypeParameterSubstitution(null, inferredTypes))); outputGroup.Add(method.Specialize(new TypeParameterSubstitution(null, inferredTypes)));
} else { } else {
outputGroup.Add(method); outputGroup.Add(method);
} }

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

@ -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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -913,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null; return null;
IMethod method = bestCandidate.Member as IMethod; IMethod method = bestCandidate.Member as IMethod;
if (method != null && method.TypeParameters.Count > 0) { if (method != null && method.TypeParameters.Count > 0) {
return new SpecializedMethod((IMethod)method.MemberDefinition, GetSubstitution(bestCandidate)); return ((IMethod)method.MemberDefinition).Specialize(GetSubstitution(bestCandidate));
} else { } else {
return bestCandidate.Member; return bestCandidate.Member;
} }
@ -921,14 +921,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
TypeParameterSubstitution GetSubstitution(Candidate candidate) TypeParameterSubstitution GetSubstitution(Candidate candidate)
{ {
SpecializedMethod sm = candidate.Member as SpecializedMethod; // Do not compose the substitutions, but merge them.
if (sm != null) { // This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce
// Do not compose the substitutions, but merge them. return new TypeParameterSubstitution(candidate.Member.Substitution.ClassTypeArguments, candidate.InferredTypes);
// This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce
return new TypeParameterSubstitution(sm.Substitution.ClassTypeArguments, candidate.InferredTypes);
} else {
return new TypeParameterSubstitution(null, candidate.InferredTypes);
}
} }
/// <summary> /// <summary>

18
ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs

@ -1,4 +1,4 @@
// //
// ReducedExtensionMethod.cs // ReducedExtensionMethod.cs
// //
// Author: // Author:
@ -150,10 +150,18 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public bool IsSpecialized { public IMethod Specialize(TypeParameterSubstitution substitution)
get { {
return baseMethod.IsSpecialized; return new ReducedExtensionMethod((IMethod)baseMethod.Specialize(substitution));
} }
IMember IMember.Specialize(TypeParameterSubstitution substitution)
{
return Specialize(substitution);
}
public bool IsParameterized {
get { return baseMethod.IsParameterized; }
} }
#endregion #endregion

1
ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs

@ -21,7 +21,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.Documentation; using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.ConsistencyCheck namespace ICSharpCode.NRefactory.ConsistencyCheck
{ {

2
ICSharpCode.NRefactory.Demo/CSDemo.cs

@ -20,7 +20,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -33,7 +32,6 @@ using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Demo namespace ICSharpCode.NRefactory.Demo
{ {

12
ICSharpCode.NRefactory.Demo/MainForm.cs

@ -17,19 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Demo namespace ICSharpCode.NRefactory.Demo
{ {

1
ICSharpCode.NRefactory.GtkDemo/MainWindow.cs

@ -34,7 +34,6 @@ using ICSharpCode.NRefactory.Semantics;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Gdk; using Gdk;
using System.Threading; using System.Threading;
using System.Diagnostics; using System.Diagnostics;

4
ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

@ -302,7 +302,7 @@ class DerivedClass : MiddleClass {
var rr = Resolve<CSharpInvocationResolveResult>(program); var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError); Assert.IsFalse(rr.IsError);
var m = (SpecializedMethod)rr.Member; var m = (IMethod)rr.Member;
Assert.AreEqual("X", m.TypeArguments.Single().Name); Assert.AreEqual("X", m.TypeArguments.Single().Name);
Assert.AreEqual("T", m.Parameters[0].Type.Name); Assert.AreEqual("T", m.Parameters[0].Type.Name);
Assert.AreEqual("X", m.Parameters[1].Type.Name); Assert.AreEqual("X", m.Parameters[1].Type.Name);
@ -489,7 +489,7 @@ class Test : IVisitor<object, object> {
}"; }";
var rr = Resolve<CSharpInvocationResolveResult>(program); var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError); Assert.IsFalse(rr.IsError);
var typeArguments = ((SpecializedMethod)rr.Member).TypeArguments; var typeArguments = ((IMethod)rr.Member).TypeArguments;
Assert.AreEqual("System.Object", typeArguments[0].ReflectionName); Assert.AreEqual("System.Object", typeArguments[0].ReflectionName);
Assert.AreEqual("System.Object", typeArguments[1].ReflectionName); Assert.AreEqual("System.Object", typeArguments[1].ReflectionName);
} }

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

@ -376,7 +376,7 @@ class TestClass {
}"; }";
var rr = Resolve<CSharpInvocationResolveResult>(program); var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError); Assert.IsFalse(rr.IsError);
SpecializedMethod m = (SpecializedMethod)rr.Member; var m = (IMethod)rr.Member;
Assert.AreEqual("System.Int32", m.TypeArguments[0].ReflectionName); Assert.AreEqual("System.Int32", m.TypeArguments[0].ReflectionName);
Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", m.Parameters[0].Type.ReflectionName); Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", m.Parameters[0].Type.ReflectionName);

4
ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

@ -352,7 +352,7 @@ class TestClass
var member = (IMethod)rr.Member; var member = (IMethod)rr.Member;
Assert.AreEqual("SelectMany", member.Name); Assert.AreEqual("SelectMany", member.Name);
Assert.AreEqual(3, member.Parameters.Count); Assert.AreEqual(3, member.Parameters.Count);
var typeArguments = ((SpecializedMethod)member).TypeArguments; var typeArguments = member.TypeArguments;
Assert.AreEqual(3, typeArguments.Count); Assert.AreEqual(3, typeArguments.Count);
Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource"); Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource");
Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection"); Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection");
@ -375,7 +375,7 @@ class TestClass
var member = (IMethod)rr.Member; var member = (IMethod)rr.Member;
Assert.AreEqual("SelectMany", member.Name); Assert.AreEqual("SelectMany", member.Name);
Assert.AreEqual(3, member.Parameters.Count); Assert.AreEqual(3, member.Parameters.Count);
var typeArguments = ((SpecializedMethod)member).TypeArguments; var typeArguments = member.TypeArguments;
Assert.AreEqual(3, typeArguments.Count); Assert.AreEqual(3, typeArguments.Count);
Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource"); Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource");
Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection"); Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection");

4
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs

@ -404,10 +404,10 @@ class TestClass {
var conversion = GetConversion(program); var conversion = GetConversion(program);
Assert.IsTrue(conversion.IsValid); Assert.IsTrue(conversion.IsValid);
Assert.IsTrue(conversion.IsMethodGroupConversion); Assert.IsTrue(conversion.IsMethodGroupConversion);
Assert.IsInstanceOf<SpecializedMethod>(conversion.Method); Assert.IsTrue(conversion.Method.IsParameterized);
Assert.AreEqual( Assert.AreEqual(
new[] { "System.Int32" }, new[] { "System.Int32" },
((SpecializedMethod)conversion.Method).TypeArguments.Select(t => t.ReflectionName).ToArray()); conversion.Method.TypeArguments.Select(t => t.ReflectionName).ToArray());
} }
[Test] [Test]

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

@ -887,7 +887,7 @@ class B
var rr = Resolve<MethodGroupResolveResult>(program); var rr = Resolve<MethodGroupResolveResult>(program);
Assert.AreEqual("X", rr.TypeArguments.Single().Name); Assert.AreEqual("X", rr.TypeArguments.Single().Name);
var m = (SpecializedMethod)rr.Methods.Single(); var m = rr.Methods.Single();
Assert.AreSame(rr.TypeArguments.Single(), m.TypeArguments.Single()); Assert.AreSame(rr.TypeArguments.Single(), m.TypeArguments.Single());
Assert.AreEqual("T", m.Parameters[0].Type.Name); Assert.AreEqual("T", m.Parameters[0].Type.Name);
Assert.AreEqual("X", m.Parameters[1].Type.Name); Assert.AreEqual("X", m.Parameters[1].Type.Name);

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

@ -203,7 +203,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
{ {
var testClass = GetTypeDefinition(typeof(GenericClass<,>)); var testClass = GetTypeDefinition(typeof(GenericClass<,>));
var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex"); var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex");
var m = new SpecializedMethod(methodDef, new TypeParameterSubstitution( var m = methodDef.Specialize(new TypeParameterSubstitution(
new[] { compilation.FindType(KnownTypeCode.Int16), compilation.FindType(KnownTypeCode.Int32) }, new[] { compilation.FindType(KnownTypeCode.Int16), compilation.FindType(KnownTypeCode.Int32) },
null null
)); ));
@ -228,18 +228,18 @@ namespace ICSharpCode.NRefactory.TypeSystem
var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex"); var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex");
// GenericClass<B, A>.GetIndex<A> // GenericClass<B, A>.GetIndex<A>
var m1 = new SpecializedMethod(methodDef, new TypeParameterSubstitution( var m1 = methodDef.Specialize(new TypeParameterSubstitution(
new[] { testClass.TypeParameters[1], testClass.TypeParameters[0] }, new[] { testClass.TypeParameters[1], testClass.TypeParameters[0] },
new[] { testClass.TypeParameters[0] } new[] { testClass.TypeParameters[0] }
)); ));
// GenericClass<string, int>.GetIndex<int> // GenericClass<string, int>.GetIndex<int>
var m2 = new SpecializedMethod(m1, new TypeParameterSubstitution( var m2 = m1.Specialize(new TypeParameterSubstitution(
new[] { compilation.FindType(KnownTypeCode.Int32), compilation.FindType(KnownTypeCode.String) }, new[] { compilation.FindType(KnownTypeCode.Int32), compilation.FindType(KnownTypeCode.String) },
null null
)); ));
// GenericClass<string, int>.GetIndex<int> // GenericClass<string, int>.GetIndex<int>
var m12 = new SpecializedMethod(methodDef, new TypeParameterSubstitution( var m12 = methodDef.Specialize(new TypeParameterSubstitution(
new[] { compilation.FindType(KnownTypeCode.String), compilation.FindType(KnownTypeCode.Int32) }, new[] { compilation.FindType(KnownTypeCode.String), compilation.FindType(KnownTypeCode.Int32) },
new[] { compilation.FindType(KnownTypeCode.Int32) } new[] { compilation.FindType(KnownTypeCode.Int32) }
)); ));
@ -253,7 +253,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreSame(method.TypeParameters[0], method.Parameters[0].Type); Assert.AreSame(method.TypeParameters[0], method.Parameters[0].Type);
Assert.AreSame(method, method.TypeParameters[0].Owner); Assert.AreSame(method, method.TypeParameters[0].Owner);
Assert.IsInstanceOf<SpecializedMethod>(method); Assert.IsInstanceOf<SpecializedMethod>(method);
Assert.AreEqual(0, ((SpecializedMethod)method).TypeArguments.Count); // the method itself is not specialized Assert.IsFalse(method.IsParameterized); // the method itself is not specialized
Assert.AreEqual(method.TypeParameters, method.TypeArguments);
var methodReference = method.ToMemberReference(); var methodReference = method.ToMemberReference();
var resolvedMethod = methodReference.Resolve(compilation.TypeResolveContext); var resolvedMethod = methodReference.Resolve(compilation.TypeResolveContext);
Assert.AreEqual(method, resolvedMethod); Assert.AreEqual(method, resolvedMethod);
@ -264,13 +265,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
{ {
var genericClass = compilation.FindType(typeof(GenericClass<string, object>)); var genericClass = compilation.FindType(typeof(GenericClass<string, object>));
IType[] methodTypeArguments = { DummyTypeParameter.GetMethodTypeParameter(0) }; IType[] methodTypeArguments = { DummyTypeParameter.GetMethodTypeParameter(0) };
var method = (SpecializedMethod)genericClass.GetMethods(methodTypeArguments, m => m.Name == "GetIndex").Single(); var method = genericClass.GetMethods(methodTypeArguments, m => m.Name == "GetIndex").Single();
// GenericClass<string,object>.GetIndex<!!0>() // GenericClass<string,object>.GetIndex<!!0>()
Assert.AreSame(method, method.TypeParameters[0].Owner); Assert.AreSame(method, method.TypeParameters[0].Owner);
Assert.AreNotEqual(method.TypeParameters[0], method.TypeArguments[0]); Assert.AreNotEqual(method.TypeParameters[0], method.TypeArguments[0]);
Assert.IsNull(((ITypeParameter)method.TypeArguments[0]).Owner); Assert.IsNull(((ITypeParameter)method.TypeArguments[0]).Owner);
// Now apply identity substitution: // Now apply identity substitution:
var method2 = new SpecializedMethod(method, TypeParameterSubstitution.Identity); var method2 = method.Specialize(TypeParameterSubstitution.Identity);
Assert.AreSame(method2, method2.TypeParameters[0].Owner); Assert.AreSame(method2, method2.TypeParameters[0].Owner);
Assert.AreNotEqual(method2.TypeParameters[0], method2.TypeArguments[0]); Assert.AreNotEqual(method2.TypeParameters[0], method2.TypeArguments[0]);
Assert.IsNull(((ITypeParameter)method2.TypeArguments[0]).Owner); Assert.IsNull(((ITypeParameter)method2.TypeArguments[0]).Owner);

1
ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs

@ -24,7 +24,6 @@ using System.Runtime.Serialization;
using System.Xml; using System.Xml;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Documentation namespace ICSharpCode.NRefactory.Documentation
{ {

2
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -139,6 +139,7 @@
<Compile Include="TypeSystem\DefaultSolutionSnapshot.cs" /> <Compile Include="TypeSystem\DefaultSolutionSnapshot.cs" />
<Compile Include="TypeSystem\DomRegion.cs" /> <Compile Include="TypeSystem\DomRegion.cs" />
<Compile Include="TypeSystem\EntityType.cs" /> <Compile Include="TypeSystem\EntityType.cs" />
<Compile Include="TypeSystem\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\TypeSystemExtensions.cs" /> <Compile Include="TypeSystem\TypeSystemExtensions.cs" />
<Compile Include="TypeSystem\FullTypeName.cs" /> <Compile Include="TypeSystem\FullTypeName.cs" />
<Compile Include="TypeSystem\IAmbience.cs" /> <Compile Include="TypeSystem\IAmbience.cs" />
@ -200,7 +201,6 @@
<Compile Include="TypeSystem\Implementation\SpecializedProperty.cs" /> <Compile Include="TypeSystem\Implementation\SpecializedProperty.cs" />
<Compile Include="TypeSystem\Implementation\SpecializingMemberReference.cs" /> <Compile Include="TypeSystem\Implementation\SpecializingMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterReference.cs" /> <Compile Include="TypeSystem\Implementation\TypeParameterReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" /> <Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />
<Compile Include="TypeSystem\Implementation\UnknownType.cs" /> <Compile Include="TypeSystem\Implementation\UnknownType.cs" />
<Compile Include="TypeSystem\Implementation\VoidTypeDefinition.cs" /> <Compile Include="TypeSystem\Implementation\VoidTypeDefinition.cs" />

1
ICSharpCode.NRefactory/Semantics/InvocationResolveResult.cs

@ -21,7 +21,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Semantics namespace ICSharpCode.NRefactory.Semantics
{ {

1
ICSharpCode.NRefactory/Semantics/ResolveResult.cs

@ -20,7 +20,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Semantics namespace ICSharpCode.NRefactory.Semantics
{ {

9
ICSharpCode.NRefactory/TypeSystem/IMember.cs

@ -18,9 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Contracts;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {
@ -180,10 +178,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
/// <summary> /// <summary>
/// If true a type substitution on this member has been performed. /// Specializes this member with the given substitution.
/// If this member is already specialized, the new substitution is composed with the existing substition.
/// </summary> /// </summary>
bool IsSpecialized { IMember Specialize(TypeParameterSubstitution substitution);
get;
}
} }
} }

30
ICSharpCode.NRefactory/TypeSystem/IMethod.cs

@ -88,31 +88,35 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Gets the unresolved method parts. /// Gets the unresolved method parts.
/// For partial methods, this returns all parts. /// For partial methods, this returns all parts.
/// Otherwise, this returns an array with a single element (new[] { UnresolvedMember }). /// Otherwise, this returns an array with a single element (new[] { UnresolvedMember }).
/// NOTE: The type will change to IReadOnlyList<IUnresolvedMethod> in future versions. /// NOTE: The type will change to IReadOnlyList&lt;IUnresolvedMethod&gt; in future versions.
/// </summary> /// </summary>
IList<IUnresolvedMethod> Parts { get; } IList<IUnresolvedMethod> Parts { get; }
/// <summary> /// <summary>
/// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)]) /// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)])
/// NOTE: The type will change to IReadOnlyList<IAttribute> in future versions. /// NOTE: The type will change to IReadOnlyList&lt;IAttribute&gt; in future versions.
/// </summary> /// </summary>
IList<IAttribute> ReturnTypeAttributes { get; } IList<IAttribute> ReturnTypeAttributes { get; }
/// <summary> /// <summary>
/// NOTE: The type will change to IReadOnlyList<ITypeParameter> in future versions. /// Gets the type parameters of this method; or an empty list if the method is not generic.
/// NOTE: The type will change to IReadOnlyList&lt;ITypeParameter&gt; in future versions.
/// </summary> /// </summary>
IList<ITypeParameter> TypeParameters { get; } IList<ITypeParameter> TypeParameters { get; }
/// <summary>
/// Gets whether this is a generic method that has been parameterized.
/// </summary>
bool IsParameterized { get; }
/// <summary> /// <summary>
/// Gets the type arguments passed to this method. /// Gets the type arguments passed to this method.
/// If only the type parameters for the class were specified and the generic method /// If the method is generic but not parameterized yet, this property returns the type parameters,
/// itself is not specialized yet, this property will return an empty list. /// as if the method was parameterized with its own type arguments (<c>void M&lt;T&gt;() { M&lt;T&gt;(); }</c>).
/// NOTE: The type will change to IReadOnlyList<IType> in future versions. ///
/// NOTE: The type will change to IReadOnlyList&lt;IType&gt; in future versions.
/// </summary> /// </summary>
IList<IType> TypeArguments { IList<IType> TypeArguments { get; }
get;
}
bool IsExtensionMethod { get; } bool IsExtensionMethod { get; }
bool IsConstructor { get; } bool IsConstructor { get; }
@ -154,5 +158,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// A reduced method doesn't contain the extension method parameter. That means that has one parameter less than it's definition. /// A reduced method doesn't contain the extension method parameter. That means that has one parameter less than it's definition.
/// </summary> /// </summary>
IMethod ReducedFrom { get; } IMethod ReducedFrom { get; }
/// <summary>
/// Specializes this method with the given substitution.
/// If this method is already specialized, the new substitution is composed with the existing substition.
/// </summary>
new IMethod Specialize(TypeParameterSubstitution substitution);
} }
} }

8
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -18,7 +18,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {
@ -84,9 +83,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary> /// <summary>
/// Gets the type arguments passed to this type. /// Gets the type arguments passed to this type.
/// If only the type parameters for the class were specified and the generic type /// If this type is a generic type definition that is not parameterized, this property returns the type parameters,
/// itself is not specialized yet or the TypeParameterCount is 0, this property will return an empty list. /// as if the type was parameterized with its own type arguments (<c>class C&lt;T&gt; { C&lt;T&gt; field; }</c>).
/// NOTE: The type will change to IReadOnlyList<IType> in future versions. ///
/// NOTE: The type will change to IReadOnlyList&lt;IType&gt; in future versions.
/// </summary> /// </summary>
IList<IType> TypeArguments { get; } IList<IType> TypeArguments { get; }

4
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs

@ -122,9 +122,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return TypeParameterSubstitution.Identity; } get { return TypeParameterSubstitution.Identity; }
} }
public bool IsSpecialized { public abstract IMember Specialize(TypeParameterSubstitution substitution);
get { return false; }
}
public virtual IMemberReference ToMemberReference() public virtual IMemberReference ToMemberReference()
{ {

5
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedEvent.cs

@ -58,5 +58,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IMethod InvokeAccessor { public IMethod InvokeAccessor {
get { return GetAccessor(ref invokeAccessor, unresolved.InvokeAccessor); } get { return GetAccessor(ref invokeAccessor, unresolved.InvokeAccessor); }
} }
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return new SpecializedEvent(this, substitution);
}
} }
} }

5
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedField.cs

@ -67,5 +67,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return rr.ConstantValue; return rr.ConstantValue;
} }
} }
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return new SpecializedField(this, substitution);
}
} }
} }

32
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -173,8 +173,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IList<IAttribute> ReturnTypeAttributes { get; private set; } public IList<IAttribute> ReturnTypeAttributes { get; private set; }
public IList<ITypeParameter> TypeParameters { get; private set; } public IList<ITypeParameter> TypeParameters { get; private set; }
static readonly IList<IType> emptyArguments = new IType[0]; public IList<IType> TypeArguments {
public IList<IType> TypeArguments { get { return emptyArguments; } } get {
// ToList() call is necessary because IList<> isn't covariant
return TypeParameters.ToList<IType>();
}
}
bool IMethod.IsParameterized {
get { return false; }
}
public bool IsExtensionMethod { get; private set; } public bool IsExtensionMethod { get; private set; }
@ -195,7 +203,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public bool IsOperator { public bool IsOperator {
get { return ((IUnresolvedMethod)unresolved).IsOperator; } get { return ((IUnresolvedMethod)unresolved).IsOperator; }
} }
public bool IsPartial { public bool IsPartial {
get { return ((IUnresolvedMethod)unresolved).IsPartial; } get { return ((IUnresolvedMethod)unresolved).IsPartial; }
} }
@ -212,13 +220,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return ((IUnresolvedMethod)unresolved).AccessorOwner != null; } get { return ((IUnresolvedMethod)unresolved).AccessorOwner != null; }
} }
public IMethod ReducedFrom { IMethod IMethod.ReducedFrom {
get { return null; } get { return null; }
} }
public IMember AccessorOwner { public IMember AccessorOwner {
get { get {
var reference = ((IUnresolvedMethod)unresolved).AccessorOwner; var reference = ((IUnresolvedMethod)unresolved).AccessorOwner;
if (reference != null) if (reference != null)
return reference.Resolve(context); return reference.Resolve(context);
else else
@ -238,6 +246,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
} }
} }
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return new SpecializedMethod(this, substitution);
}
IMethod IMethod.Specialize(TypeParameterSubstitution substitution)
{
return new SpecializedMethod(this, substitution);
}
public override string ToString() public override string ToString()
{ {
StringBuilder b = new StringBuilder("["); StringBuilder b = new StringBuilder("[");

5
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedProperty.cs

@ -72,5 +72,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.Parameters.Select(p => p.Type.ToTypeReference()).ToList()); this.Parameters.Select(p => p.Type.ToTypeReference()).ToList());
} }
} }
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return new SpecializedProperty(this, substitution);
}
} }
} }

8
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -494,12 +494,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return parts[0].TypeParameters.Count; } get { return parts[0].TypeParameters.Count; }
} }
IList<IType> typeArguments;
public IList<IType> TypeArguments { public IList<IType> TypeArguments {
get { get {
if (typeArguments == null) // ToList() call is necessary because IList<> isn't covariant
typeArguments = new ReadOnlyCollection<IType> (TypeParameters.Cast<IType> ().ToArray ()); return TypeParameters.ToList<IType>();
return typeArguments;
} }
} }
@ -797,7 +795,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
using (var busyLock = BusyManager.Enter(this)) { using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) { if (busyLock.Success) {
return coClass.GetConstructors(filter, options) return coClass.GetConstructors(filter, options)
.Select(m => new SpecializedMethod(m, TypeParameterSubstitution.Identity) { DeclaringType = this }); .Select(m => new SpecializedMethod(m, m.Substitution) { DeclaringType = this });
} }
} }
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;

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

@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public SpecializedEvent(IEvent eventDefinition, TypeParameterSubstitution substitution) public SpecializedEvent(IEvent eventDefinition, TypeParameterSubstitution substitution)
: base(eventDefinition) : base(eventDefinition)
{ {
this.eventDefinition = eventDefinition;
AddSubstitution(substitution); AddSubstitution(substitution);
this.eventDefinition = (IEvent)base.baseMember;
} }
public bool CanAdd { public bool CanAdd {

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

@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public SpecializedField(IField fieldDefinition, TypeParameterSubstitution substitution) public SpecializedField(IField fieldDefinition, TypeParameterSubstitution substitution)
: base(fieldDefinition) : base(fieldDefinition)
{ {
this.fieldDefinition = fieldDefinition;
AddSubstitution(substitution); AddSubstitution(substitution);
this.fieldDefinition = (IField)base.baseMember;
} }
public bool IsReadOnly { public bool IsReadOnly {

34
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs

@ -42,15 +42,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{ {
if (memberDefinition == null) if (memberDefinition == null)
throw new ArgumentNullException("memberDefinition"); throw new ArgumentNullException("memberDefinition");
if (memberDefinition is SpecializedMember)
throw new ArgumentException("Member definition cannot be specialized. Please use IMember.Specialize() instead of directly constructing SpecializedMember instances.");
SpecializedMember sm = memberDefinition as SpecializedMember; this.baseMember = memberDefinition;
if (sm != null) { this.substitution = TypeParameterSubstitution.Identity;
this.baseMember = sm.baseMember;
this.substitution = sm.substitution;
} else {
this.baseMember = memberDefinition;
this.substitution = TypeParameterSubstitution.Identity;
}
} }
/// <summary> /// <summary>
@ -63,20 +59,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.substitution = TypeParameterSubstitution.Compose(newSubstitution, this.substitution); this.substitution = TypeParameterSubstitution.Compose(newSubstitution, this.substitution);
} }
public static SpecializedMember Create(IMember memberDefinition, TypeParameterSubstitution substitution) [Obsolete("Use IMember.Specialize() instead")]
public static IMember Create(IMember memberDefinition, TypeParameterSubstitution substitution)
{ {
if (memberDefinition == null) { if (memberDefinition == null) {
return null; return null;
} else if (memberDefinition is IMethod) {
return new SpecializedMethod((IMethod)memberDefinition, substitution);
} else if (memberDefinition is IProperty) {
return new SpecializedProperty((IProperty)memberDefinition, substitution);
} else if (memberDefinition is IField) {
return new SpecializedField((IField)memberDefinition, substitution);
} else if (memberDefinition is IEvent) {
return new SpecializedEvent((IEvent)memberDefinition, substitution);
} else { } else {
throw new NotSupportedException("Unknown IMember: " + memberDefinition); return memberDefinition.Specialize(substitution);
} }
} }
@ -104,7 +93,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (result != null) { if (result != null) {
return result; return result;
} else { } else {
var sm = new SpecializedMethod(accessorDefinition, substitution); var sm = accessorDefinition.Specialize(substitution);
//sm.AccessorOwner = this; //sm.AccessorOwner = this;
return LazyInit.GetOrSet(ref cachingField, sm); return LazyInit.GetOrSet(ref cachingField, sm);
} }
@ -217,7 +206,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
var definitionImplementations = baseMember.ImplementedInterfaceMembers; var definitionImplementations = baseMember.ImplementedInterfaceMembers;
IMember[] result = new IMember[definitionImplementations.Count]; IMember[] result = new IMember[definitionImplementations.Count];
for (int i = 0; i < result.Length; i++) { for (int i = 0; i < result.Length; i++) {
result[i] = SpecializedMember.Create(definitionImplementations[i], substitution); result[i] = definitionImplementations[i].Specialize(substitution);
} }
return result; return result;
} }
@ -302,8 +291,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return baseMember.ParentAssembly; } get { return baseMember.ParentAssembly; }
} }
public bool IsSpecialized { public virtual IMember Specialize(TypeParameterSubstitution newSubstitution)
get { return true; } {
return baseMember.Specialize(TypeParameterSubstitution.Compose(newSubstitution, this.substitution));
} }
public override bool Equals(object obj) public override bool Equals(object obj)

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

@ -33,20 +33,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{ {
readonly IMethod methodDefinition; readonly IMethod methodDefinition;
readonly ITypeParameter[] specializedTypeParameters; readonly ITypeParameter[] specializedTypeParameters;
readonly bool genericMethodIsSpecialized; readonly bool isParameterized;
readonly TypeParameterSubstitution substitutionWithoutSpecializedTypeParameters; readonly TypeParameterSubstitution substitutionWithoutSpecializedTypeParameters;
public SpecializedMethod(IMethod methodDefinition, TypeParameterSubstitution substitution) public SpecializedMethod(IMethod methodDefinition, TypeParameterSubstitution substitution)
: base(methodDefinition) : base(methodDefinition)
{ {
SpecializedMethod specializedMethodDefinition = methodDefinition as SpecializedMethod; if (substitution == null)
if (specializedMethodDefinition != null) throw new ArgumentNullException("substitution");
this.genericMethodIsSpecialized = specializedMethodDefinition.genericMethodIsSpecialized;
// The base ctor might have unpacked a SpecializedMember
// (in case we are specializing an already-specialized method)
methodDefinition = (IMethod)base.baseMember;
this.methodDefinition = methodDefinition; this.methodDefinition = methodDefinition;
this.isParameterized = substitution.MethodTypeArguments != null;
if (methodDefinition.TypeParameters.Count > 0) { if (methodDefinition.TypeParameters.Count > 0) {
// The method is generic, so we need to specialize the type parameters // The method is generic, so we need to specialize the type parameters
// (for specializing the constraints, and also to set the correct Owner) // (for specializing the constraints, and also to set the correct Owner)
@ -54,7 +50,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
for (int i = 0; i < specializedTypeParameters.Length; i++) { for (int i = 0; i < specializedTypeParameters.Length; i++) {
specializedTypeParameters[i] = new SpecializedTypeParameter(methodDefinition.TypeParameters[i], this); specializedTypeParameters[i] = new SpecializedTypeParameter(methodDefinition.TypeParameters[i], this);
} }
if (!genericMethodIsSpecialized) { if (!isParameterized) {
// Add substitution that replaces the base method's type parameters with our specialized version // Add substitution that replaces the base method's type parameters with our specialized version
// but do this only if the type parameters on the baseMember have not already been substituted // but do this only if the type parameters on the baseMember have not already been substituted
substitutionWithoutSpecializedTypeParameters = this.Substitution; substitutionWithoutSpecializedTypeParameters = this.Substitution;
@ -71,8 +67,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
// in this case. // in this case.
substitutionWithoutSpecializedTypeParameters = this.Substitution; substitutionWithoutSpecializedTypeParameters = this.Substitution;
} }
if (substitution != null && substitution.MethodTypeArguments != null && methodDefinition.TypeParameters.Count > 0)
this.genericMethodIsSpecialized = true;
if (specializedTypeParameters != null) { if (specializedTypeParameters != null) {
// Set the substitution on the type parameters to the final composed substitution // Set the substitution on the type parameters to the final composed substitution
foreach (var tp in specializedTypeParameters.OfType<SpecializedTypeParameter>()) { foreach (var tp in specializedTypeParameters.OfType<SpecializedTypeParameter>()) {
@ -82,13 +76,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
} }
} }
/// <summary>
/// Gets the type arguments passed to this method.
/// If only the type parameters for the class were specified and the generic method
/// itself is not specialized yet, this property will return an empty list.
/// </summary>
public IList<IType> TypeArguments { public IList<IType> TypeArguments {
get { return genericMethodIsSpecialized ? this.Substitution.MethodTypeArguments : EmptyList<IType>.Instance; } get { return this.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance; }
}
public bool IsParameterized {
get { return isParameterized; }
} }
public IList<IUnresolvedMethod> Parts { public IList<IUnresolvedMethod> Parts {
@ -137,8 +130,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return methodDefinition.IsAccessor; } get { return methodDefinition.IsAccessor; }
} }
public IMethod ReducedFrom { public IMethod ReducedFrom {
get { return null; } get { return null; }
} }
IMember accessorOwner; IMember accessorOwner;
@ -149,7 +142,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (result != null) { if (result != null) {
return result; return result;
} else { } else {
result = SpecializedMember.Create(methodDefinition.AccessorOwner, this.Substitution); result = methodDefinition.AccessorOwner.Specialize(this.Substitution);
return LazyInit.GetOrSet(ref accessorOwner, result); return LazyInit.GetOrSet(ref accessorOwner, result);
} }
} }
@ -161,7 +154,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override IMemberReference ToMemberReference() public override IMemberReference ToMemberReference()
{ {
// Pass the MethodTypeArguments to the SpecializingMemberReference only if // Pass the MethodTypeArguments to the SpecializingMemberReference only if
// the generic method itself is specialized, not if the generic method is only // the generic method itself is parameterized, not if the generic method is only
// specialized with class type arguments. // specialized with class type arguments.
// This is necessary due to this part of the ToMemberReference() contract: // This is necessary due to this part of the ToMemberReference() contract:
@ -171,7 +164,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
// This means that if the method itself isn't specialized, // This means that if the method itself isn't specialized,
// we must not include TypeParameterReferences for the specialized type parameters // we must not include TypeParameterReferences for the specialized type parameters
// in the resulting member reference. // in the resulting member reference.
if (genericMethodIsSpecialized) { if (isParameterized) {
return new SpecializingMemberReference( return new SpecializingMemberReference(
baseMember.ToMemberReference(), baseMember.ToMemberReference(),
ToTypeReference(base.Substitution.ClassTypeArguments), ToTypeReference(base.Substitution.ClassTypeArguments),
@ -196,12 +189,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
} }
} }
public new IMethod MemberDefinition { public override IMember Specialize(TypeParameterSubstitution newSubstitution)
get { {
return (IMethod)base.MemberDefinition; return methodDefinition.Specialize(TypeParameterSubstitution.Compose(newSubstitution, substitutionWithoutSpecializedTypeParameters));
}
} }
IMethod IMethod.Specialize(TypeParameterSubstitution newSubstitution)
{
return methodDefinition.Specialize(TypeParameterSubstitution.Compose(newSubstitution, substitutionWithoutSpecializedTypeParameters));
}
public override string ToString() public override string ToString()
{ {
StringBuilder b = new StringBuilder("["); StringBuilder b = new StringBuilder("[");

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

@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public SpecializedProperty(IProperty propertyDefinition, TypeParameterSubstitution substitution) public SpecializedProperty(IProperty propertyDefinition, TypeParameterSubstitution substitution)
: base(propertyDefinition) : base(propertyDefinition)
{ {
this.propertyDefinition = propertyDefinition;
AddSubstitution(substitution); AddSubstitution(substitution);
this.propertyDefinition = (IProperty)base.baseMember;
} }
public bool CanGet { public bool CanGet {

3
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializingMemberReference.cs

@ -40,8 +40,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IMember Resolve(ITypeResolveContext context) public IMember Resolve(ITypeResolveContext context)
{ {
var memberDefinition = memberDefinitionReference.Resolve(context); var memberDefinition = memberDefinitionReference.Resolve(context);
return SpecializedMember.Create( return memberDefinition.Specialize(
memberDefinition,
new TypeParameterSubstitution( new TypeParameterSubstitution(
classTypeArgumentReferences != null ? classTypeArgumentReferences.Resolve(context) : null, classTypeArgumentReferences != null ? classTypeArgumentReferences.Resolve(context) : null,
methodTypeArgumentReferences != null ? methodTypeArgumentReferences.Resolve(context) : null methodTypeArgumentReferences != null ? methodTypeArgumentReferences.Resolve(context) : null

3
ICSharpCode.NRefactory/TypeSystem/InheritanceHelper.cs

@ -57,6 +57,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
yield return member; yield return member;
} }
// TODO: can we get rid of this upcast?
SpecializedMember specializedMember = member as SpecializedMember; SpecializedMember specializedMember = member as SpecializedMember;
member = member.MemberDefinition; member = member.MemberDefinition;
@ -79,7 +80,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
foreach (IMember baseMember in baseMembers) { foreach (IMember baseMember in baseMembers) {
if (SignatureComparer.Ordinal.Equals(member, baseMember)) { if (SignatureComparer.Ordinal.Equals(member, baseMember)) {
if (specializedMember != null) if (specializedMember != null)
yield return SpecializedMember.Create(baseMember, specializedMember.Substitution); yield return baseMember.Specialize(specializedMember.Substitution);
else else
yield return baseMember; yield return baseMember;
} }

2
ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs

@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {

1
ICSharpCode.NRefactory/TypeSystem/NullableType.cs

@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {

2
ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs → ICSharpCode.NRefactory/TypeSystem/TypeParameterSubstitution.cs

@ -20,7 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation namespace ICSharpCode.NRefactory.TypeSystem
{ {
/// <summary> /// <summary>
/// Substitutes class and method type parameters. /// Substitutes class and method type parameters.

2
NRefactory.sln

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
# SharpDevelop 4.3 # SharpDevelop 5.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
Packages\ICSharpCode.NRefactory.nuspec = Packages\ICSharpCode.NRefactory.nuspec Packages\ICSharpCode.NRefactory.nuspec = Packages\ICSharpCode.NRefactory.nuspec

Loading…
Cancel
Save