📄 resolveresult.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1379 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
#region ResolveResult
/// <summary>
/// The base class of all resolve results.
/// This class is used whenever an expression is not one of the special expressions
/// (having their own ResolveResult class).
/// The ResolveResult specified the location where Resolve was called (Class+Member)
/// and the type of the resolved expression.
/// </summary>
public class ResolveResult
{
IClass callingClass;
IMember callingMember;
IReturnType resolvedType;
public ResolveResult(IClass callingClass, IMember callingMember, IReturnType resolvedType)
{
// if (callingMember != null && callingMember.DeclaringType != callingClass)
// throw new ArgumentException("callingMember.DeclaringType must be equal to callingClass");
this.callingClass = callingClass;
this.callingMember = callingMember;
this.resolvedType = resolvedType;
}
/// <summary>
/// Gets the class that contained the expression used to get this ResolveResult.
/// Can be null when the class is unknown.
/// </summary>
public IClass CallingClass {
get {
return callingClass;
}
}
/// <summary>
/// Gets the member (method or property in <see cref="CallingClass"/>) that contained the
/// expression used to get this ResolveResult.
/// Can be null when the expression was not inside a member or the member is unknown.
/// </summary>
public IMember CallingMember {
get {
return callingMember;
}
}
/// <summary>
/// Gets the type of the resolved expression.
/// Can be null when the type cannot be represented by a IReturnType (e.g. when the
/// expression was a namespace name).
/// </summary>
public IReturnType ResolvedType {
get {
return resolvedType;
}
set {
resolvedType = value;
}
}
public virtual ArrayList GetCompletionData(IProjectContent projectContent)
{
return GetCompletionData(projectContent.Language, false);
}
protected ArrayList GetCompletionData(LanguageProperties language, bool showStatic)
{
if (resolvedType == null) return null;
ArrayList res = new ArrayList();
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(resolvedType.GetUnderlyingClass());
foreach (IMethod m in resolvedType.GetMethods()) {
if (language.ShowMember(m, showStatic) && m.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(m);
}
foreach (IEvent e in resolvedType.GetEvents()) {
if (language.ShowMember(e, showStatic) && e.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(e);
}
foreach (IField f in resolvedType.GetFields()) {
if (language.ShowMember(f, showStatic) && f.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(f);
}
foreach (IProperty p in resolvedType.GetProperties()) {
if (language.ShowMember(p, showStatic) && p.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(p);
}
if (!showStatic && callingClass != null) {
AddExtensions(language, res, callingClass, resolvedType);
}
return res;
}
/// <summary>
/// Adds extension methods to <paramref name="res"/>.
/// </summary>
public static void AddExtensions(LanguageProperties language, ArrayList res, IClass callingClass, IReturnType resolvedType)
{
if (language == null)
throw new ArgumentNullException("language");
if (res == null)
throw new ArgumentNullException("res");
if (callingClass == null)
throw new ArgumentNullException("callingClass");
if (resolvedType == null)
throw new ArgumentNullException("resolvedType");
bool supportsExtensionMethods = language.SupportsExtensionMethods;
bool supportsExtensionProperties = language.SupportsExtensionProperties;
if (supportsExtensionMethods || supportsExtensionProperties) {
ArrayList list = new ArrayList();
IMethod dummyMethod = new DefaultMethod("dummy", ReflectionReturnType.Void, ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass);
NRefactoryResolver.NRefactoryResolver.AddContentsFromCalling(list, callingClass, dummyMethod);
NRefactoryResolver.NRefactoryResolver.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass);
bool searchExtensionsInClasses = language.SearchExtensionsInClasses;
foreach (object o in list) {
if (supportsExtensionMethods && o is IMethod || supportsExtensionProperties && o is IProperty) {
TryAddExtension(language, res, o as IMethodOrProperty, resolvedType);
} else if (searchExtensionsInClasses && o is IClass) {
IClass c = o as IClass;
if (c.HasExtensionMethods) {
if (supportsExtensionProperties) {
foreach (IProperty p in c.Properties) {
TryAddExtension(language, res, p, resolvedType);
}
}
if (supportsExtensionMethods) {
foreach (IMethod m in c.Methods) {
TryAddExtension(language, res, m, resolvedType);
}
}
}
}
}
}
}
static void TryAddExtension(LanguageProperties language, ArrayList res, IMethodOrProperty ext, IReturnType resolvedType)
{
// accept only extension methods
if (!ext.IsExtensionMethod)
return;
// don't add extension if method with that name already exists
// but allow overloading extension methods
foreach (IMember member in res) {
IMethodOrProperty p = member as IMethodOrProperty;
if (p != null && p.IsExtensionMethod)
continue;
if (language.NameComparer.Equals(member.Name, ext.Name)) {
return;
}
}
// now add the extension method if it fits the type
if (MemberLookupHelper.ConversionExists(resolvedType, ext.Parameters[0].ReturnType)) {
IMethod method = ext as IMethod;
if (method != null && method.TypeParameters.Count > 0) {
IReturnType[] typeArguments = new IReturnType[method.TypeParameters.Count];
MemberLookupHelper.InferTypeArgument(method.Parameters[0].ReturnType, resolvedType, typeArguments);
for (int i = 0; i < typeArguments.Length; i++) {
if (typeArguments[i] != null) {
ext = (IMethod)ext.Clone();
ext.ReturnType = ConstructedReturnType.TranslateType(ext.ReturnType, typeArguments, true);
for (int j = 0; j < ext.Parameters.Count; ++j) {
ext.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(ext.Parameters[j].ReturnType, typeArguments, true);
}
break;
}
}
}
res.Add(ext);
}
}
public virtual FilePosition GetDefinitionPosition()
{
// this is only possible on some subclasses of ResolveResult
return null;
}
}
#endregion
#region MixedResolveResult
/// <summary>
/// The MixedResolveResult is used when an expression can have multiple meanings, for example
/// "Size" in a class deriving from "Control".
/// </summary>
public class MixedResolveResult : ResolveResult
{
ResolveResult primaryResult, secondaryResult;
public ResolveResult PrimaryResult {
get {
return primaryResult;
}
}
public IEnumerable<ResolveResult> Results {
get {
yield return primaryResult;
yield return secondaryResult;
}
}
public TypeResolveResult TypeResult {
get {
if (primaryResult is TypeResolveResult)
return (TypeResolveResult)primaryResult;
if (secondaryResult is TypeResolveResult)
return (TypeResolveResult)secondaryResult;
return null;
}
}
public MixedResolveResult(ResolveResult primaryResult, ResolveResult secondaryResult)
: base(primaryResult.CallingClass, primaryResult.CallingMember, primaryResult.ResolvedType)
{
this.primaryResult = primaryResult;
this.secondaryResult = secondaryResult;
}
public override FilePosition GetDefinitionPosition()
{
return primaryResult.GetDefinitionPosition();
}
public override ArrayList GetCompletionData(IProjectContent projectContent)
{
ArrayList result = primaryResult.GetCompletionData(projectContent);
ArrayList result2 = secondaryResult.GetCompletionData(projectContent);
if (result == null) return result2;
if (result2 == null) return result;
foreach (object o in result2) {
if (!result.Contains(o))
result.Add(o);
}
return result;
}
}
#endregion
#region LocalResolveResult
/// <summary>
/// The LocalResolveResult is used when an expression was a simple local variable
/// or parameter.
/// </summary>
/// <remarks>
/// For fields in the current class, a MemberResolveResult is used, so "e" is not always
/// a LocalResolveResult.
/// </remarks>
public class LocalResolveResult : ResolveResult
{
IField field;
bool isParameter;
public LocalResolveResult(IMember callingMember, IField field)
: base(callingMember.DeclaringType, callingMember, field.ReturnType)
{
if (callingMember == null)
throw new ArgumentNullException("callingMember");
if (field == null)
throw new ArgumentNullException("field");
this.field = field;
this.isParameter = field.IsParameter;
if (!isParameter && !field.IsLocalVariable) {
throw new ArgumentException("the field must either be a local variable-field or a parameter-field");
}
}
/// <summary>
/// Gets the field representing the local variable.
/// </summary>
public IField Field {
get {
return field;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -