diff --git a/src/Main/Base/Test/Utils/MockDefaultReturnType.cs b/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
index fdbbde1ff4..61307cc8c0 100644
--- a/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
+++ b/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
@@ -154,5 +154,10 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils
throw new NotImplementedException();
}
}
+
+ public IReturnType GetDirectReturnType()
+ {
+ return this;
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
index bba40cc76a..884f25252e 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
@@ -98,6 +98,7 @@
+
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
index a571031e4b..785a50ca99 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
@@ -131,5 +131,10 @@ namespace ICSharpCode.SharpDevelop.Dom
}
public virtual bool? IsReferenceType { get { return null; } }
+
+ public virtual IReturnType GetDirectReturnType()
+ {
+ return this;
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ArrayReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ArrayReturnType.cs
index 8ecde6403b..fc6cc10ff1 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ArrayReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ArrayReturnType.cs
@@ -42,6 +42,15 @@ namespace ICSharpCode.SharpDevelop.Dom
this.dimensions = dimensions;
}
+ public override IReturnType GetDirectReturnType()
+ {
+ IReturnType newElementType = elementType.GetDirectReturnType();
+ if (newElementType == elementType)
+ return this;
+ else
+ return new ArrayReturnType(pc, newElementType, dimensions);
+ }
+
public override bool Equals(IReturnType rt)
{
if (rt == null || !rt.IsArrayReturnType) return false;
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs
index d0f7e0f9ad..71a8d85068 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs
@@ -63,6 +63,23 @@ namespace ICSharpCode.SharpDevelop.Dom
return this.DotNetName.GetHashCode();
}
+ public override IReturnType GetDirectReturnType()
+ {
+ IReturnType newBaseType = baseType.GetDirectReturnType();
+ IReturnType[] newTypeArguments = new IReturnType[typeArguments.Count];
+ bool typeArgumentsChanged = false;
+ for (int i = 0; i < typeArguments.Count; i++) {
+ if (typeArguments[i] != null)
+ newTypeArguments[i] = typeArguments[i].GetDirectReturnType();
+ if (typeArguments[i] != newTypeArguments[i])
+ typeArgumentsChanged = true;
+ }
+ if (baseType == newBaseType && !typeArgumentsChanged)
+ return this;
+ else
+ return new ConstructedReturnType(newBaseType, newTypeArguments);
+ }
+
public override IReturnType BaseType {
get {
return baseType;
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DecoratingReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DecoratingReturnType.cs
index 6760ce56ff..fbe1548d3a 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DecoratingReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DecoratingReturnType.cs
@@ -24,5 +24,10 @@ namespace ICSharpCode.SharpDevelop.Dom
}
public abstract override T CastToDecoratingReturnType();
+
+ public override IReturnType GetDirectReturnType()
+ {
+ return this;
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/PointerReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/PointerReturnType.cs
index c6f81bf96d..4ecdf0091b 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/PointerReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/PointerReturnType.cs
@@ -37,6 +37,15 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
+ public override IReturnType GetDirectReturnType()
+ {
+ IReturnType newBaseType = baseType.GetDirectReturnType();
+ if (newBaseType == baseType)
+ return this;
+ else
+ return new PointerReturnType(newBaseType);
+ }
+
public override bool Equals(IReturnType rt)
{
if (rt == null) return false;
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
index f50acf3618..cc2c1a7842 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
@@ -226,5 +226,13 @@ namespace ICSharpCode.SharpDevelop.Dom
return tmp;
}
}
+
+ public virtual IReturnType GetDirectReturnType()
+ {
+ IReturnType baseType = BaseType;
+ IReturnType tmp = (baseType != null && TryEnter()) ? baseType.GetDirectReturnType() : UnknownReturnType.Instance;
+ Leave();
+ return tmp;
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ReferenceReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ReferenceReturnType.cs
index c99c539067..26c94b0d0d 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ReferenceReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ReferenceReturnType.cs
@@ -21,6 +21,17 @@ namespace ICSharpCode.SharpDevelop.Dom
this.baseType = baseType;
}
+ public override IReturnType GetDirectReturnType()
+ {
+ if (baseType == null)
+ return this;
+ IReturnType newBaseType = baseType.GetDirectReturnType();
+ if (newBaseType == baseType)
+ return this;
+ else
+ return new ReferenceReturnType(newBaseType);
+ }
+
public override IReturnType BaseType {
get { return baseType; }
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/UnknownReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/UnknownReturnType.cs
new file mode 100644
index 0000000000..07af11ad1b
--- /dev/null
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/UnknownReturnType.cs
@@ -0,0 +1,22 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.SharpDevelop.Dom
+{
+ sealed class UnknownReturnType : ProxyReturnType
+ {
+ public static readonly UnknownReturnType Instance = new UnknownReturnType();
+
+ public override IReturnType BaseType {
+ get {
+ return null;
+ }
+ }
+ }
+}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
index 128c66acf6..de366e3e44 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
@@ -127,6 +127,23 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsConstructedReturnType { get; }
ConstructedReturnType CastToConstructedReturnType();
+ ///
+ /// Gets whether the type is a reference type or value type.
+ ///
+ ///
+ /// true, if the type is a reference type.
+ /// false, if the type is a value type.
+ /// null, if the type is not known (e.g. generic type argument or type not found)
+ ///
bool? IsReferenceType { get; }
+
+ ///
+ /// Gets an identical return type that binds directly to the underlying class, so
+ /// that repeatedly calling methods does not cause repeated class lookups.
+ /// The direct return type will always point to the old version of the class, so don't
+ /// store direct return types!
+ ///
+ /// This method never returns null.
+ IReturnType GetDirectReturnType();
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs
index 19ee68a92f..3e91c03f75 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs
@@ -112,6 +112,9 @@ namespace ICSharpCode.SharpDevelop.Dom
if (callingClass == null)
throw new ArgumentNullException("callingClass");
+ // convert resolvedType into direct type to speed up the IsApplicable lookups
+ resolvedType = resolvedType.GetDirectReturnType();
+
foreach (IMethodOrProperty mp in CtrlSpaceResolveHelper.FindAllExtensions(language, callingClass)) {
TryAddExtension(language, res, mp, resolvedType);
}