diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
index 7a5b18af60..7a4084067a 100644
--- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
+++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
@@ -178,6 +178,10 @@
+
+
+
+
diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
index fc08d0b2c2..e6d55860ca 100644
--- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
@@ -617,9 +617,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
if (parameter == null)
throw new ArgumentNullException("parameter");
- DefaultParameter p = new DefaultParameter();
- p.Name = parameter.Name;
- p.Type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter, entity: parentMember);
+ var type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter, entity: parentMember);
+ DefaultParameter p = new DefaultParameter(type, parameter.Name);
if (parameter.HasCustomAttributes)
AddAttributes(parameter, p.Attributes);
diff --git a/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs b/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs
index b089fe8894..140a1eae1f 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs
@@ -23,6 +23,29 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
public class ConstructedType : Immutable, IType
{
+ sealed class Substitution : TypeVisitor
+ {
+ readonly IType[] typeArguments;
+
+ public Substitution(IType[] typeArguments)
+ {
+ this.typeArguments = typeArguments;
+ }
+
+ public override IType VisitTypeParameter(ITypeParameter type)
+ {
+ int index = type.Index;
+ if (type.ParentClass != null) {
+ if (index >= 0 && index < typeArguments.Length)
+ return typeArguments[index];
+ else
+ return SharedTypes.UnknownType;
+ } else {
+ return base.VisitTypeParameter(type);
+ }
+ }
+ }
+
readonly ITypeDefinition genericType;
readonly IType[] typeArguments;
@@ -118,7 +141,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IEnumerable GetBaseTypes(ITypeResolveContext context)
{
- throw new NotImplementedException();
+ Substitution substitution = new Substitution(typeArguments);
+ return genericType.GetBaseTypes(context).Select(t => t.AcceptVisitor(substitution));
}
public IList GetNestedTypes(ITypeResolveContext context)
@@ -128,22 +152,54 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IList GetMethods(ITypeResolveContext context)
{
- throw new NotImplementedException();
+ Substitution substitution = new Substitution(typeArguments);
+ IList methods = genericType.GetMethods(context);
+ for (int i = 0; i < methods.Count; i++) {
+ SpecializedMethod m = new SpecializedMethod(methods[i]);
+ m.SetDeclaringType(this);
+ m.SubstituteTypes(context, substitution);
+ methods[i] = m;
+ }
+ return methods;
}
public IList GetProperties(ITypeResolveContext context)
{
- throw new NotImplementedException();
+ Substitution substitution = new Substitution(typeArguments);
+ IList properties = genericType.GetProperties(context);
+ for (int i = 0; i < properties.Count; i++) {
+ SpecializedProperty p = new SpecializedProperty(properties[i]);
+ p.SetDeclaringType(this);
+ p.SubstituteTypes(context, substitution);
+ properties[i] = p;
+ }
+ return properties;
}
public IList GetFields(ITypeResolveContext context)
{
- throw new NotImplementedException();
+ Substitution substitution = new Substitution(typeArguments);
+ IList fields = genericType.GetFields(context);
+ for (int i = 0; i < fields.Count; i++) {
+ SpecializedField f = new SpecializedField(fields[i]);
+ f.SetDeclaringType(this);
+ f.ReturnType = f.ReturnType.Resolve(context).AcceptVisitor(substitution);
+ fields[i] = f;
+ }
+ return fields;
}
public IList GetEvents(ITypeResolveContext context)
{
- throw new NotImplementedException();
+ Substitution substitution = new Substitution(typeArguments);
+ IList events = genericType.GetEvents(context);
+ for (int i = 0; i < events.Count; i++) {
+ SpecializedEvent e = new SpecializedEvent(events[i]);
+ e.SetDeclaringType(this);
+ e.ReturnType = e.ReturnType.Resolve(context).AcceptVisitor(substitution);
+ events[i] = e;
+ }
+ return events;
}
public override bool Equals(object obj)
diff --git a/ICSharpCode.NRefactory/TypeSystem/IMember.cs b/ICSharpCode.NRefactory/TypeSystem/IMember.cs
index 0c64a6c76a..f5e120ce07 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IMember.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IMember.cs
@@ -27,11 +27,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
IType DeclaringType { get; }
///
- /// Gets the generic member this member is based on.
- /// Returns null if this is not a specialized member.
+ /// Gets the original member definition for this member.
+ /// Returns this if this is not a specialized member.
/// Specialized members are the result of overload resolution with type substitution.
///
- IMember GenericMember { get; }
+ IMember MemberDefinition { get; }
///
/// Gets the return type of this member.
@@ -81,8 +81,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
- IMember IMember.GenericMember {
+ IMember IMember.MemberDefinition {
get {
+ Contract.Ensures(Contract.Result() != null);
return null;
}
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
index 7406c101c2..3faff4ae0a 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
@@ -28,21 +28,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
/// Gets all methods that can be called on this return type.
///
+ /// A new mutable list
IList GetMethods(ITypeResolveContext context);
///
/// Gets all properties that can be called on this return type.
///
+ /// A new mutable list
IList GetProperties(ITypeResolveContext context);
///
/// Gets all fields that can be called on this return type.
///
+ /// A new mutable list
IList GetFields(ITypeResolveContext context);
///
/// Gets all events that can be called on this return type.
///
+ /// A new mutable list
IList GetEvents(ITypeResolveContext context);
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
index 43ee6f2b10..97aef7d680 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
@@ -51,7 +51,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.name = name;
}
- /* do we really need copy constructor (for specialized members?)
+ ///
+ /// Copy constructor
+ ///
protected AbstractMember(IMember member)
{
if (member == null)
@@ -64,6 +66,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.bodyRegion = member.BodyRegion;
this.name = member.Name;
this.accessibility = member.Accessibility;
+ this.entityType = member.EntityType;
this.IsSealed = member.IsSealed;
this.IsAbstract = member.IsAbstract;
this.IsShadowing = member.IsShadowing;
@@ -73,14 +76,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.IsStatic = member.IsStatic;
}
- static IList CopyList(IList inputList)
+ protected static IList CopyList(IList inputList)
{
if (inputList.Count == 0)
return null;
else
return new List(inputList);
}
- */
public ITypeDefinition DeclaringTypeDefinition {
get { return declaringTypeDefinition; }
@@ -90,8 +92,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return declaringTypeDefinition; }
}
- public virtual IMember GenericMember {
- get { return null; }
+ public virtual IMember MemberDefinition {
+ get { return this; }
}
public ITypeReference ReturnType {
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultEvent.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultEvent.cs
index 880a2695fb..38cf3467ce 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultEvent.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultEvent.cs
@@ -23,6 +23,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
}
+ ///
+ /// Copy constructor
+ ///
+ protected DefaultEvent(IEvent ev)
+ : base(ev)
+ {
+ this.CanAdd = ev.CanAdd;
+ this.addAccessibility = ev.AddAccessibility;
+ this.CanRemove = ev.CanRemove;
+ this.removeAccessibility = ev.RemoveAccessibility;
+ this.CanInvoke = ev.CanInvoke;
+ this.invokeAccessibility = ev.InvokeAccessibility;
+ }
+
public bool CanAdd {
get { return flags[FlagCanAdd]; }
set {
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultField.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultField.cs
index 361f14f073..9e811e8df7 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultField.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultField.cs
@@ -27,6 +27,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
}
+ protected DefaultField(IField f) : base(f)
+ {
+ this.constantValue = f.ConstantValue;
+ this.IsReadOnly = f.IsReadOnly;
+ this.IsVolatile = f.IsVolatile;
+ }
+
public bool IsConst {
get { return constantValue != null; }
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs
index 17243d0756..b77904f3d3 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMethod.cs
@@ -31,6 +31,17 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
}
+ ///
+ /// Copy constructor
+ ///
+ protected DefaultMethod(IMethod method) : base(method)
+ {
+ returnTypeAttributes = CopyList(returnTypeAttributes);
+ typeParameters = CopyList(typeParameters);
+ parameters = CopyList(parameters);
+ this.IsExtensionMethod = method.IsExtensionMethod;
+ }
+
public IList ReturnTypeAttributes {
get {
if (returnTypeAttributes == null)
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs
index e9304a80fe..377684a7c9 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs
@@ -20,6 +20,31 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
DomRegion region;
byte flags;
+ public DefaultParameter(ITypeReference type, string name)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (name == null)
+ throw new ArgumentNullException("name");
+ this.type = type;
+ this.name = name;
+ }
+
+ ///
+ /// Copy constructor
+ ///
+ public DefaultParameter(IParameter p)
+ {
+ this.name = p.Name;
+ this.type = p.Type;
+ this.attributes = p.Attributes;
+ this.defaultValue = p.DefaultValue;
+ this.region = p.Region;
+ this.IsRef = p.IsRef;
+ this.IsOut = p.IsOut;
+ this.IsParams = p.IsParams;
+ }
+
protected override void FreezeInternal()
{
type.Freeze();
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultProperty.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultProperty.cs
index 855df24da4..8e85a924c6 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultProperty.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultProperty.cs
@@ -30,6 +30,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
}
+ protected DefaultProperty(IProperty p) : base(p)
+ {
+ this.getterAccessibility = p.GetterAccessibility;
+ this.setterAccessibility = p.SetterAccessibility;
+ this.parameters = CopyList(p.Parameters);
+ this.IsIndexer = p.IsIndexer;
+ this.CanGet = p.CanGet;
+ this.CanSet = p.CanSet;
+ }
+
public bool IsIndexer {
get { return flags[FlagIsIndexer]; }
set {
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedEvent.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedEvent.cs
new file mode 100644
index 0000000000..6c2fdbe105
--- /dev/null
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedEvent.cs
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ ///
+ /// Represents a specialized IEvent (e.g. after type substitution).
+ ///
+ public class SpecializedEvent : DefaultEvent
+ {
+ readonly IMember memberDefinition;
+ IType declaringType;
+
+ public SpecializedEvent(IEvent e) : base(e)
+ {
+ this.memberDefinition = e.MemberDefinition;
+ this.declaringType = e.DeclaringType;
+ }
+
+ public override IType DeclaringType {
+ get { return declaringType; }
+ }
+
+ public void SetDeclaringType(IType declaringType)
+ {
+ CheckBeforeMutation();
+ this.declaringType = declaringType;
+ }
+
+ public override IMember MemberDefinition {
+ get { return memberDefinition; }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedField.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedField.cs
new file mode 100644
index 0000000000..ccdf9d5044
--- /dev/null
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedField.cs
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ ///
+ /// Represents a specialized IField (e.g. after type substitution).
+ ///
+ public class SpecializedField : DefaultField
+ {
+ readonly IMember memberDefinition;
+ IType declaringType;
+
+ public SpecializedField(IField f) : base(f)
+ {
+ this.memberDefinition = f.MemberDefinition;
+ this.declaringType = f.DeclaringType;
+ }
+
+ public override IType DeclaringType {
+ get { return declaringType; }
+ }
+
+ public void SetDeclaringType(IType declaringType)
+ {
+ CheckBeforeMutation();
+ this.declaringType = declaringType;
+ }
+
+ public override IMember MemberDefinition {
+ get { return memberDefinition; }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
new file mode 100644
index 0000000000..99717ee193
--- /dev/null
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ ///
+ /// Represents a specialized IMethod (e.g. after type substitution).
+ ///
+ public class SpecializedMethod : DefaultMethod
+ {
+ readonly IMember memberDefinition;
+ IType declaringType;
+
+ public SpecializedMethod(IMethod m) : base(m)
+ {
+ this.memberDefinition = m.MemberDefinition;
+ this.declaringType = m.DeclaringType;
+ }
+
+ public override IType DeclaringType {
+ get { return declaringType; }
+ }
+
+ public void SetDeclaringType(IType declaringType)
+ {
+ CheckBeforeMutation();
+ this.declaringType = declaringType;
+ }
+
+ public override IMember MemberDefinition {
+ get { return memberDefinition; }
+ }
+
+ ///
+ /// Performts type substitution in parameter types and in the return type.
+ ///
+ public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution)
+ {
+ this.ReturnType = this.ReturnType.Resolve(context).AcceptVisitor(substitution);
+ var p = this.Parameters;
+ for (int i = 0; i < p.Count; i++) {
+ IType newType = p[i].Type.Resolve(context).AcceptVisitor(substitution);
+ if (newType != p[i].Type) {
+ p[i] = new DefaultParameter(p[i]) { Type = newType };
+ }
+ }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs
new file mode 100644
index 0000000000..59c9a7c009
--- /dev/null
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ ///
+ /// Represents a specialized IProperty (e.g. after type substitution).
+ ///
+ public class SpecializedProperty : DefaultProperty
+ {
+ readonly IMember memberDefinition;
+ IType declaringType;
+
+ public SpecializedProperty(IProperty p) : base(p)
+ {
+ this.memberDefinition = p.MemberDefinition;
+ this.declaringType = p.DeclaringType;
+ }
+
+ public override IType DeclaringType {
+ get { return declaringType; }
+ }
+
+ public void SetDeclaringType(IType declaringType)
+ {
+ CheckBeforeMutation();
+ this.declaringType = declaringType;
+ }
+
+ public override IMember MemberDefinition {
+ get { return memberDefinition; }
+ }
+
+ ///
+ /// Performts type substitution in parameter types and in the return type.
+ ///
+ public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution)
+ {
+ this.ReturnType = this.ReturnType.Resolve(context).AcceptVisitor(substitution);
+ var p = this.Parameters;
+ for (int i = 0; i < p.Count; i++) {
+ IType newType = p[i].Type.Resolve(context).AcceptVisitor(substitution);
+ if (newType != p[i].Type) {
+ p[i] = new DefaultParameter(p[i]) { Type = newType };
+ }
+ }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/TypeVisitor.cs b/ICSharpCode.NRefactory/TypeSystem/TypeVisitor.cs
index 774cfda4f8..af8ae4ca8f 100644
--- a/ICSharpCode.NRefactory/TypeSystem/TypeVisitor.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/TypeVisitor.cs
@@ -6,7 +6,7 @@ using System;
namespace ICSharpCode.NRefactory.TypeSystem
{
///
- /// Description of ITypeVisitor.
+ /// Base class for the visitor pattern on .
///
public abstract class TypeVisitor
{