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); }