⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resolvevisitor.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1417 $</version>
// </file>

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using Boo.Lang.Compiler.Ast;

namespace Grunwald.BooBinding.CodeCompletion
{
	public class ResolveVisitor : DepthFirstVisitor
	{
		#region Field + Constructor
		BooResolver resolver;
		ResolveResult resolveResult;
		IClass callingClass;
		IProjectContent projectContent;
		ICompilationUnit cu;
		
		public ResolveVisitor(BooResolver resolver)
		{
			this.resolver = resolver;
			this.callingClass = resolver.CallingClass;
			this.projectContent = resolver.ProjectContent;
			this.cu = resolver.CompilationUnit;
		}
		
		public ResolveResult ResolveResult {
			get {
				return resolveResult;
			}
		}
		#endregion
		
		#region Make Result
		void ClearResult()
		{
			resolveResult = null;
		}
		
		void MakeResult(IReturnType type)
		{
			if (type == null)
				ClearResult();
			else
				resolveResult = new ResolveResult(callingClass, resolver.CallingMember, type);
		}
		
		void MakeLiteralResult(string fullTypeName)
		{
			resolveResult = new ResolveResult(callingClass, resolver.CallingMember,
			                                  new GetClassReturnType(projectContent, fullTypeName, 0));
		}
		
		void MakeResult(IMember member)
		{
			IField field = member as IField;
			if (field != null && (field.IsLocalVariable || field.IsParameter)) {
				resolveResult = new LocalResolveResult(resolver.CallingMember, field);
			} else if (member != null) {
				resolveResult = new MemberResolveResult(callingClass, resolver.CallingMember, member);
			} else {
				ClearResult();
			}
		}
		
		void MakeTypeResult(IClass c)
		{
			resolveResult = new TypeResolveResult(callingClass, resolver.CallingMember, c);
		}
		
		void MakeTypeResult(IReturnType rt)
		{
			resolveResult = new TypeResolveResult(callingClass, resolver.CallingMember, rt);
		}
		
		void MakeMethodResult(IReturnType type, string methodName)
		{
			resolveResult = new MethodResolveResult(callingClass, resolver.CallingMember, type, methodName);
			IMethod m = (resolveResult as MethodResolveResult).GetMethodIfSingleOverload();
			if (m != null) {
				AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(cu);
				amrt.MethodReturnType = m.ReturnType;
				amrt.MethodParameters = m.Parameters;
				resolveResult.ResolvedType = amrt;
			}
		}
		
		void MakeNamespaceResult(string namespaceName)
		{
			resolveResult = new NamespaceResolveResult(callingClass, resolver.CallingMember, namespaceName);
		}
		
		static bool IsSameName(string name1, string name2)
		{
			// boo is currently always case sensitive
			return name1 == name2;
		}
		#endregion
		
		#region Resolve Identifier
		public override void OnReferenceExpression(ReferenceExpression node)
		{
			string identifier = node.Name;
			bool wasResolved = ResolveIdentifier(identifier);
			if (wasResolved && resolveResult is TypeResolveResult) {
				return;
			}
			// was not resolved or was resolved as local, member etc.
			ResolveResult oldResult = resolveResult;
			ClearResult();
			// Try to resolve as type:
			IReturnType t = projectContent.SearchType(identifier, 0, callingClass, cu, resolver.CaretLine, resolver.CaretColumn);
			if (t != null) {
				MakeTypeResult(t);
			} else {
				if (callingClass != null) {
					if (resolver.CallingMember is IMethod) {
						foreach (ITypeParameter typeParameter in (resolver.CallingMember as IMethod).TypeParameters) {
							if (IsSameName(identifier, typeParameter.Name)) {
								MakeTypeResult(new GenericReturnType(typeParameter));
								return;
							}
						}
					}
					foreach (ITypeParameter typeParameter in callingClass.TypeParameters) {
						if (IsSameName(identifier, typeParameter.Name)) {
							MakeTypeResult(new GenericReturnType(typeParameter));
							return;
						}
					}
				}
			}
			if (!wasResolved)
				return; // return type result, if existant
			if (resolveResult == null) {
				resolveResult = oldResult;
			} else {
				// TODO: return type or mixed dependant on context!
				resolveResult = new MixedResolveResult(oldResult, resolveResult);
			}
		}
		
		bool ResolveIdentifier(string identifier)
		{
			IField local;
			ClearResult();
			if (resolver.CallingMember != null) {
				local = resolver.FindLocalVariable(identifier, false);
				if (local != null) {
					MakeResult(local);
					return true;
				}
				
				IMethodOrProperty method = resolver.CallingMember;
				if (method != null) {
					foreach (IParameter p in method.Parameters) {
						if (IsSameName(p.Name, identifier)) {
							MakeResult(new DefaultField.ParameterField(p.ReturnType, p.Name, p.Region, callingClass));
							return true;
						}
					}
					if (method is IProperty && IsSameName(identifier, "value")) {
						if (((IProperty)method).SetterRegion.IsInside(resolver.CaretLine, resolver.CaretColumn)) {
							MakeResult(new DefaultField.ParameterField(method.ReturnType, "value", method.Region, callingClass));
							return true;
						}
					}
				}
			}
			
			{ // Find members of this class or enclosing classes
				IClass tmp = callingClass;
				while (tmp != null) {
					if (ResolveMember(tmp.DefaultReturnType, identifier))
						return true;
					tmp = tmp.DeclaringType;
				}
			}
			
			string namespaceName = projectContent.SearchNamespace(identifier, callingClass, cu, resolver.CaretLine, resolver.CaretColumn);
			if (namespaceName != null && namespaceName.Length > 0) {
				MakeNamespaceResult(namespaceName);
				return true;
			}
			
			// Boo can import classes+modules:
			foreach (object o in resolver.GetImportedNamespaceContents()) {
				IClass c = o as IClass;
				if (c != null && IsSameName(identifier, c.Name)) {
					MakeTypeResult(c);
					return true;
				}
				IMember member = o as IMember;
				if (member != null && IsSameName(identifier, member.Name)) {
					if (member is IMethod) {
						MakeMethodResult(member.DeclaringType.DefaultReturnType, member.Name);
					} else {
						MakeResult(member);
					}
					return true;
				}
			}
			
			local = resolver.FindLocalVariable(identifier, true);
			if (local != null) {
				MakeResult(local);
				return true;
			}
			
			return false;
		}
		#endregion
		
		#region OnGenericReferenceExpression
		public override void OnGenericReferenceExpression(GenericReferenceExpression node)
		{
			MakeTypeResult(ConstructTypeFromGenericReferenceExpression(node));
		}
		
		public ConstructedReturnType ConstructTypeFromGenericReferenceExpression(GenericReferenceExpression node)
		{
			Stack<Expression> stack = new Stack<Expression>();
			Expression expr = node;
			while (expr != null) {
				stack.Push(expr);
				if (expr is MemberReferenceExpression) {
					expr = ((MemberReferenceExpression)expr).Target;
				} else if (expr is GenericReferenceExpression) {
					expr = ((GenericReferenceExpression)expr).Target;
				} else {
					expr = null;
				}
			}
			StringBuilder name = new StringBuilder();
			List<IReturnType> typeArguments = new List<IReturnType>();
			while (stack.Count > 0) {
				expr = stack.Pop();
				if (expr is MemberReferenceExpression) {
					name.Append('.');
					name.Append(((MemberReferenceExpression)expr).Name);
				} else if (expr is GenericReferenceExpression) {
					foreach (TypeReference tr in ((GenericReferenceExpression)expr).GenericArguments) {
						typeArguments.Add(ConvertVisitor.CreateReturnType(tr, callingClass,
						                                                  resolver.CallingMember,
						                                                  resolver.CaretLine,
						                                                  resolver.CaretColumn,
						                                                  projectContent));
					}
				} else if (expr is ReferenceExpression) {
					name.Append(((ReferenceExpression)expr).Name);
				} else {
					LoggingService.Warn("Unknown expression in GenericReferenceExpression: " + expr);
				}
			}
			IReturnType rt = projectContent.SearchType(name.ToString(), typeArguments.Count, callingClass,
			                                           cu, resolver.CaretLine, resolver.CaretColumn);
			return new ConstructedReturnType(rt, typeArguments);
		}
		#endregion
		
		#region Resolve Member
		public override void OnMemberReferenceExpression(MemberReferenceExpression node)
		{
			ClearResult();
			node.Target.Accept(this);
			if (resolveResult is NamespaceResolveResult) {
				string namespaceName = (resolveResult as NamespaceResolveResult).Name;
				string combinedName;
				if (namespaceName.Length == 0)
					combinedName = node.Name;
				else
					combinedName = namespaceName + "." + node.Name;
				if (projectContent.NamespaceExists(combinedName)) {
					MakeNamespaceResult(combinedName);
					return;
				}
				IClass c = projectContent.GetClass(combinedName);
				if (c != null) {
					MakeTypeResult(c);
					return;
				}
				
				ClearResult();
				// go through the members of the modules in that namespace
				foreach (object o in projectContent.GetNamespaceContents(namespaceName)) {
					IMember member = o as IMember;
					if (member != null && IsSameName(member.Name, node.Name)) {
						if (member is IMethod) {
							MakeMethodResult(member.DeclaringType.DefaultReturnType, member.Name);
						} else {
							MakeResult(member);
						}
						break;
					}
				}
			} else {
				if (resolveResult != null) {
					if (resolveResult is TypeResolveResult) {
						IClass rClass = (resolveResult as TypeResolveResult).ResolvedClass;
						if (rClass != null) {
							foreach (IClass baseClass in rClass.ClassInheritanceTree) {
								foreach (IClass innerClass in baseClass.InnerClasses) {
									if (IsSameName(innerClass.Name, node.Name)) {
										MakeTypeResult(innerClass);
										return;
									}
								}
							}
						}
					}
					ResolveMember(resolveResult.ResolvedType, node.Name);
				}
			}
		}
		
		bool ResolveMember(IReturnType type, string memberName)
		{
			ClearResult();
			if (type == null)
				return false;
			bool isClassInInheritanceTree = false;
			if (callingClass != null)
				isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(type.GetUnderlyingClass());
			foreach (IProperty p in type.GetProperties()) {
				if (IsSameName(p.Name, memberName)) {
					MakeResult(p);
					return true;
				}
			}
			foreach (IField f in type.GetFields()) {
				if (IsSameName(f.Name, memberName)) {
					MakeResult(f);
					return true;
				}
			}
			foreach (IEvent e in type.GetEvents()) {
				if (IsSameName(e.Name, memberName)) {
					MakeResult(e);
					return true;
				}
			}
			foreach (IMethod m in type.GetMethods()) {
				if (IsSameName(m.Name, memberName)) {
					MakeMethodResult(type, memberName);
					return true;
				}
			}
			if (callingClass != null) {
				ArrayList list = new ArrayList();
				ResolveResult.AddExtensions(callingClass.ProjectContent.Language, list, callingClass, type);
				foreach (IMethodOrProperty mp in list) {
					if (IsSameName(mp.Name, memberName)) {
						if (mp is IMethod)
							MakeMethodResult(type, memberName);
						else
							MakeResult(mp);
						return true;
					}
				}
			}
			return false;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -