Browse Source

Implement 'ToMemberReference()' and 'InterfaceImplementations' on specialized members.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
5f8dcf4f7a
  1. 24
      ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs
  2. 17
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  3. 12
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  4. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  5. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs
  6. 37
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
  7. 16
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
  8. 73
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializingMemberReference.cs

24
ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs

@ -53,6 +53,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -53,6 +53,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
.SetAssemblyName(typeof(TypeSystemTests).Assembly.GetName().Name);
}
[Test]
public void ConvertStandaloneTypeReference()
{
var typeRef = new MemberType(new SimpleType("System"), "Array").ToTypeReference();
Assert.AreEqual(compilation.FindType(KnownTypeCode.Array), typeRef.Resolve(compilation.TypeResolveContext));
}
[Test]
public void ExplicitDisposableImplementation()
{
@ -82,10 +89,21 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -82,10 +89,21 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
}
[Test]
public void ConvertStandaloneTypeReference()
public void ExplicitImplementationOfUnifiedMethods()
{
var typeRef = new MemberType(new SimpleType("System"), "Array").ToTypeReference();
Assert.AreEqual(compilation.FindType(KnownTypeCode.Array), typeRef.Resolve(compilation.TypeResolveContext));
IType type = compilation.FindType(typeof(ExplicitGenericInterfaceImplementationWithUnifiableMethods<int, int>));
Assert.AreEqual(2, type.GetMethods(m => m.IsExplicitInterfaceImplementation).Count());
foreach (IMethod method in type.GetMethods(m => m.IsExplicitInterfaceImplementation)) {
Assert.AreEqual(1, method.InterfaceImplementations.Count, method.ToString());
Assert.AreEqual("System.Int32", method.Parameters.Single().Type.ReflectionName);
IMethod interfaceMethod = (IMethod)method.InterfaceImplementations.Single();
Assert.AreEqual("System.Int32", interfaceMethod.Parameters.Single().Type.ReflectionName);
var genericParamType = ((IMethod)method.MemberDefinition).Parameters.Single().Type;
var interfaceGenericParamType = ((IMethod)interfaceMethod.MemberDefinition).Parameters.Single().Type;
Assert.AreEqual(TypeKind.TypeParameter, genericParamType.Kind);
Assert.AreEqual(TypeKind.TypeParameter, interfaceGenericParamType.Kind);
Assert.AreEqual(genericParamType.ReflectionName, interfaceGenericParamType.ReflectionName);
}
}
}

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

@ -186,4 +186,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase @@ -186,4 +186,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
void IGenericInterface<string>.Test<T>(string a, T b) {}
void IGenericInterface<string>.Test<T>(string a, ref T b) {}
}
public interface IGenericInterfaceWithUnifiableMethods<T, S>
{
void Test(T a);
void Test(S a);
}
public class ImplementationOfUnifiedMethods : IGenericInterfaceWithUnifiableMethods<int, int>
{
public void Test(int a) {}
}
public class ExplicitGenericInterfaceImplementationWithUnifiableMethods<T, S> : IGenericInterfaceWithUnifiableMethods<T, S>
{
void IGenericInterfaceWithUnifiableMethods<T, S>.Test(T a) {}
void IGenericInterfaceWithUnifiableMethods<T, S>.Test(S a) {}
}
}

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

@ -676,5 +676,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -676,5 +676,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual("System.Double", arg.Type.ReflectionName);
Assert.AreEqual(1.0, arg.ConstantValue);
}
[Test, Ignore("Getting implicit interface implementations is not yet implemented.")]
public void ImplicitImplementationOfUnifiedMethods()
{
ITypeDefinition type = GetTypeDefinition(typeof(ImplementationOfUnifiedMethods));
IMethod test = type.Methods.Single(m => m.Name == "Test");
Assert.AreEqual(2, test.InterfaceImplementations.Count);
Assert.AreEqual("Int32", ((IMethod)test.InterfaceImplementations[0]).Parameters.Single().Type.Name);
Assert.AreEqual("Int32", ((IMethod)test.InterfaceImplementations[1]).Parameters.Single().Type.Name);
Assert.AreEqual("T", ((IMethod)test.InterfaceImplementations[0].MemberDefinition).Parameters.Single().Type.Name);
Assert.AreEqual("S", ((IMethod)test.InterfaceImplementations[1].MemberDefinition).Parameters.Single().Type.Name);
}
}
}

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -161,6 +161,7 @@ @@ -161,6 +161,7 @@
<Compile Include="TypeSystem\Implementation\SpecializedMember.cs" />
<Compile Include="TypeSystem\Implementation\SpecializedMethod.cs" />
<Compile Include="TypeSystem\Implementation\SpecializedProperty.cs" />
<Compile Include="TypeSystem\Implementation\SpecializingMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />

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

@ -24,7 +24,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -24,7 +24,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// <summary>
/// References a member that is an explicit interface implementation.
/// </summary>
public class ExplicitInterfaceImplementationMemberReference : IMemberReference
[Serializable]
public sealed class ExplicitInterfaceImplementationMemberReference : IMemberReference
{
ITypeReference typeReference;
IMemberReference interfaceMemberReference;

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

@ -20,6 +20,8 @@ using System; @@ -20,6 +20,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
@ -50,7 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -50,7 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IMemberReference ToMemberReference()
{
return new DefaultMemberReference(this.EntityType, this.DeclaringType.ToTypeReference(), this.Name);
return new SpecializingMemberReference(declaringType.ToTypeReference(), memberDefinition.ToMemberReference());
}
internal static TypeVisitor GetSubstitution(IType declaringType)
@ -127,8 +129,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -127,8 +129,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return memberDefinition.Attributes; }
}
IList<IMember> IMember.InterfaceImplementations {
get { throw new NotImplementedException(); }
IList<IMember> interfaceImplementations;
public IList<IMember> InterfaceImplementations {
get {
return LazyInitializer.EnsureInitialized(ref interfaceImplementations, FindInterfaceImplementations);
}
}
IList<IMember> FindInterfaceImplementations()
{
var definitionImplementations = memberDefinition.InterfaceImplementations;
IMember[] result = new IMember[definitionImplementations.Count];
for (int i = 0; i < result.Length; i++) {
result[i] = Specialize(definitionImplementations[i]);
}
return result;
}
/// <summary>
/// Specialize another member using the same type arguments as this member.
/// </summary>
protected virtual IMember Specialize(IMember otherMember)
{
return SpecializingMemberReference.CreateSpecializedMember(declaringType, memberDefinition, null);
}
public bool IsExplicitInterfaceImplementation {
@ -275,13 +299,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -275,13 +299,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return parameters; }
}
public override IMemberReference ToMemberReference()
{
return new DefaultMemberReference(
this.EntityType, this.DeclaringType.ToTypeReference(), this.Name, 0,
this.Parameters.Select(p => p.Type.ToTypeReference()).ToList());
}
public override string ToString()
{
StringBuilder b = new StringBuilder("[");

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

@ -97,14 +97,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -97,14 +97,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override IMemberReference ToMemberReference()
{
if (this.TypeParameters.Count == 0)
return base.ToMemberReference();
// TODO: Implement SpecializedMethod.ToMemberReference()
throw new NotImplementedException();
return new SpecializingMemberReference(
this.DeclaringType.ToTypeReference(),
this.MemberDefinition.ToMemberReference(),
typeArguments.Select(ta => ta.ToTypeReference()).ToList()
);
}
protected override IMember Specialize(IMember otherMember)
{
return SpecializingMemberReference.CreateSpecializedMember(this.DeclaringType, this.MemberDefinition, typeArguments);
}
/// <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 {
get { return typeArguments; }

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

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
// 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
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
[Serializable]
public sealed class SpecializingMemberReference : IMemberReference
{
ITypeReference declaringTypeReference;
IMemberReference memberDefinitionReference;
IList<ITypeReference> typeArgumentReferences;
public SpecializingMemberReference(ITypeReference declaringTypeReference, IMemberReference memberDefinitionReference, IList<ITypeReference> typeArgumentReferences = null)
{
if (declaringTypeReference == null)
throw new ArgumentNullException("declaringTypeReference");
if (memberDefinitionReference == null)
throw new ArgumentNullException("memberDefinitionReference");
this.declaringTypeReference = declaringTypeReference;
this.memberDefinitionReference = memberDefinitionReference;
this.typeArgumentReferences = typeArgumentReferences;
}
public IMember Resolve(ITypeResolveContext context)
{
var declaringType = declaringTypeReference.Resolve(context);
var memberDefinition = memberDefinitionReference.Resolve(context);
IType[] typeArguments = null;
if (typeArgumentReferences != null) {
typeArguments = new IType[typeArgumentReferences.Count];
for (int i = 0; i < typeArguments.Length; i++) {
typeArguments[i] = typeArgumentReferences[i].Resolve(context);
}
}
return CreateSpecializedMember(declaringType, memberDefinition, typeArguments);
}
internal static IMember CreateSpecializedMember(IType declaringType, IMember memberDefinition, IList<IType> typeArguments)
{
if (memberDefinition == null) {
return null;
} else if (memberDefinition is IMethod) {
return new SpecializedMethod(declaringType, (IMethod)memberDefinition, typeArguments);
} else if (memberDefinition is IProperty) {
return new SpecializedProperty(declaringType, (IProperty)memberDefinition);
} else if (memberDefinition is IField) {
return new SpecializedField(declaringType, (IField)memberDefinition);
} else if (memberDefinition is IEvent) {
return new SpecializedEvent(declaringType, (IEvent)memberDefinition);
} else {
throw new NotSupportedException("Unknown IMember: " + memberDefinition);
}
}
}
}
Loading…
Cancel
Save