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

📄 resolvevisitor.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
📖 第 1 页 / 共 2 页
字号:
		#endregion
		
		#region Resolve Method Invocation
		public override void OnMethodInvocationExpression(MethodInvocationExpression node)
		{
			ClearResult();
			node.Target.Accept(this);
			if (resolveResult is MixedResolveResult) {
				MixedResolveResult mixed = (MixedResolveResult)resolveResult;
				resolveResult = mixed.TypeResult;
				foreach (ResolveResult rr in mixed.Results) {
					if (rr is MethodResolveResult) {
						resolveResult = rr;
						break;
					}
				}
			}
			if (resolveResult == null)
				return;
			
			if (resolveResult is MethodResolveResult) {
				// normal method call
				string methodName = ((MethodResolveResult)resolveResult).Name;
				IReturnType containingType = ((MethodResolveResult)resolveResult).ContainingType;
				
				ResolveMethodInType(containingType, methodName, node.Arguments);
			} else if (resolveResult is TypeResolveResult) {
				TypeResolveResult trr = (TypeResolveResult)resolveResult;
				if (trr.ResolvedClass != null) {
					if (trr.ResolvedClass.FullyQualifiedName == "array") {
						ResolveArrayCreation(node.Arguments);
						return;
					}
					
					List<IMethod> methods = new List<IMethod>();
					bool isClassInInheritanceTree = false;
					if (callingClass != null)
						isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(trr.ResolvedClass);
					
					foreach (IMethod m in trr.ResolvedClass.Methods) {
						if (m.IsConstructor && !m.IsStatic
						    && m.IsAccessible(callingClass, isClassInInheritanceTree))
						{
							methods.Add(m);
						}
					}
					if (methods.Count == 0) {
						methods.Add(ICSharpCode.SharpDevelop.Dom.Constructor.CreateDefault(trr.ResolvedClass));
					}
					ResolveInvocation(methods, node.Arguments);
					if (resolveResult != null)
						resolveResult.ResolvedType = trr.ResolvedType;
				} else {
					ClearResult();
				}
			} else if (resolveResult.ResolvedType != null) {
				// maybe event or callable call or call on System.Type -> constructor by reflection
				IClass c = resolveResult.ResolvedType.GetUnderlyingClass();
				if (c != null) {
					if (c.ClassType == ClassType.Delegate) {
						// find the delegate's invoke method
						IMethod invoke = c.Methods.Find(delegate(IMethod innerMethod) { return innerMethod.Name == "Invoke"; });
						if (invoke != null) {
							resolveResult.ResolvedType = invoke.ReturnType;
						}
					} else if (c.FullyQualifiedName == "System.Type") {
						resolveResult.ResolvedType = ReflectionReturnType.Object;
					} else {
						ClearResult();
					}
				} else {
					ClearResult();
				}
			} else {
				ClearResult();
			}
		}
		
		void ResolveArrayCreation(ExpressionCollection arguments)
		{
			if (arguments.Count == 2) {
				ClearResult();
				arguments[0].Accept(this);
				TypeResolveResult trr = resolveResult as TypeResolveResult;
				if (trr != null) {
					MakeResult(new ArrayReturnType(trr.ResolvedType, 1));
				}
			} else {
				ResolveMethodInType(new GetClassReturnType(projectContent, "Boo.Lang.Builtins", 0),
				                    "array", arguments);
			}
		}
		
		void ResolveMethodInType(IReturnType containingType, string methodName, ExpressionCollection arguments)
		{
			List<IMethod> methods = new List<IMethod>();
			bool isClassInInheritanceTree = false;
			if (callingClass != null)
				isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(containingType.GetUnderlyingClass());
			
			foreach (IMethod m in containingType.GetMethods()) {
				if (IsSameName(m.Name, methodName)
				    && m.IsAccessible(callingClass, isClassInInheritanceTree)
				   ) {
					methods.Add(m);
				}
			}
			if (methods.Count == 0) {
				ArrayList list = new ArrayList();
				ResolveResult.AddExtensions(callingClass.ProjectContent.Language, list, callingClass, containingType);
				foreach (IMethodOrProperty mp in list) {
					if (IsSameName(mp.Name, methodName) && mp is IMethod) {
						IMethod m = (IMethod)mp.Clone();
						m.Parameters.RemoveAt(0);
						methods.Add(m);
					}
				}
			}
			ResolveInvocation(methods, arguments);
		}
		
		void ResolveInvocation(List<IMethod> methods, ExpressionCollection arguments)
		{
			ClearResult();
			if (methods.Count == 0) {
				return;
			}
			// MemberLookupHelper does type argument inference and type substitution for us
			IReturnType[] types = new IReturnType[arguments.Count];
			for (int i = 0; i < types.Length; ++i) {
				arguments[i].Accept(this);
				types[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
				ClearResult();
			}
			MakeResult(MemberLookupHelper.FindOverload(methods, new IReturnType[0], types));
		}
		#endregion
		
		#region Resolve Slice Expression
		public override void OnSlicingExpression(SlicingExpression node)
		{
			ClearResult();
			Visit(node.Target);
			if (node.Indices.Count > 0) {
				Slice slice = node.Indices[0];
				if (slice.End != null) {
					// Boo slice, returns a part of the source -> same type as source
					return;
				}
			}
			IReturnType rt = (resolveResult != null) ? resolveResult.ResolvedType : null;
			if (rt == null) {
				ClearResult();
				return;
			}
			List<IProperty> indexers = rt.GetProperties();
			// remove non-indexers:
			for (int i = 0; i < indexers.Count; i++) {
				if (!indexers[i].IsIndexer)
					indexers.RemoveAt(i--);
			}
			IReturnType[] parameters = new IReturnType[node.Indices.Count];
			for (int i = 0; i < parameters.Length; i++) {
				Expression expr = node.Indices[i].Begin as Expression;
				if (expr != null) {
					ClearResult();
					Visit(expr);
					parameters[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
				}
			}
			MakeResult(MemberLookupHelper.FindOverload(indexers.ToArray(), parameters));
		}
		#endregion
		
		public override void OnGeneratorExpression(GeneratorExpression node)
		{
			ClearResult();
			node.Expression.Accept(this);
			
			if (resolveResult != null) {
				IClass enumerable = ProjectContentRegistry.Mscorlib.GetClass("System.Collections.Generic.IEnumerable", 1);
				MakeResult(new ConstructedReturnType(enumerable.DefaultReturnType, new IReturnType[] { resolveResult.ResolvedType }));
			} else {
				MakeResult(new GetClassReturnType(projectContent, "System.Collections.IEnumerable", 0));
			}
		}
		
		public override void OnBinaryExpression(BinaryExpression node)
		{
			switch (node.Operator) {
				case BinaryOperatorType.GreaterThan:
				case BinaryOperatorType.GreaterThanOrEqual:
				case BinaryOperatorType.Equality:
				case BinaryOperatorType.Inequality:
				case BinaryOperatorType.LessThan:
				case BinaryOperatorType.LessThanOrEqual:
				case BinaryOperatorType.Match:
				case BinaryOperatorType.Member:
				case BinaryOperatorType.NotMatch:
				case BinaryOperatorType.NotMember:
				case BinaryOperatorType.ReferenceEquality:
				case BinaryOperatorType.ReferenceInequality:
				case BinaryOperatorType.TypeTest:
					MakeResult(ReflectionReturnType.Bool);
					break;
				default:
					if (node.Left == null) {
						if (node.Right == null) {
							ClearResult();
						} else {
							node.Right.Accept(this);
						}
						return;
					} else if (node.Right == null) {
						node.Left.Accept(this);
						return;
					}
					node.Left.Accept(this);
					IReturnType left = (resolveResult != null) ? resolveResult.ResolvedType : null;
					node.Right.Accept(this);
					IReturnType right = (resolveResult != null) ? resolveResult.ResolvedType : null;
					MakeResult(MemberLookupHelper.GetCommonType(left, right));
					break;
			}
		}
		
		protected override void OnError(Node node, Exception error)
		{
			MessageService.ShowError(error, "ResolveVisitor: error processing " + node);
		}
		
		public override void OnCallableBlockExpression(CallableBlockExpression node)
		{
			AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(cu);
			if (node.ReturnType != null) {
				amrt.MethodReturnType = ConvertType(node.ReturnType);
			} else {
				amrt.MethodReturnType = new InferredReturnType(node.Body, resolver.CallingClass,
				                                               node.ContainsAnnotation("inline"));
			}
			ConvertVisitor.AddParameters(node.Parameters, amrt.MethodParameters, resolver.CallingMember, resolver.CallingClass ?? new DefaultClass(resolver.CompilationUnit, "__Dummy"));
			MakeResult(amrt);
		}
		
		public override void OnCallableTypeReference(CallableTypeReference node)
		{
			MakeTypeResult(ConvertType(node));
		}
		
		public override void OnRELiteralExpression(RELiteralExpression node)
		{
			MakeLiteralResult("System.Text.RegularExpressions.Regex");
		}
		
		public override void OnCharLiteralExpression(CharLiteralExpression node)
		{
			MakeLiteralResult("System.Char");
		}
		
		public override void OnArrayLiteralExpression(ArrayLiteralExpression node)
		{
			if (node.Type != null) {
				MakeResult(ConvertType(node.Type));
				return;
			}
			IReturnType elementType = null;
			foreach (Expression expr in node.Items) {
				ClearResult();
				expr.Accept(this);
				IReturnType thisType = (resolveResult != null) ? resolveResult.ResolvedType : null;
				if (elementType == null)
					elementType = thisType;
				else if (thisType != null)
					elementType = MemberLookupHelper.GetCommonType(elementType, thisType);
			}
			if (elementType == null)
				elementType = ReflectionReturnType.Object;
			MakeResult(new ArrayReturnType(elementType, 1));
		}
		
		public override void OnTryCastExpression(TryCastExpression node)
		{
			MakeResult(ConvertType(node.Type));
		}
		
		public override void OnCastExpression(CastExpression node)
		{
			MakeResult(ConvertType(node.Type));
		}
		
		public override void OnBoolLiteralExpression(BoolLiteralExpression node)
		{
			MakeResult(ReflectionReturnType.Bool);
		}
		
		public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
		{
			if (node.IsSingle)
				MakeLiteralResult("System.Single");
			else
				MakeLiteralResult("System.Double");
		}
		
		public override void OnListLiteralExpression(ListLiteralExpression node)
		{
			MakeLiteralResult("Boo.Lang.List");
		}
		
		public override void OnHashLiteralExpression(HashLiteralExpression node)
		{
			MakeLiteralResult("Boo.Lang.Hash");
		}
		
		public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
		{
			if (node.IsLong)
				MakeLiteralResult("System.Int64");
			else
				MakeResult(ReflectionReturnType.Int);
		}
		
		public override void OnNullLiteralExpression(NullLiteralExpression node)
		{
			MakeResult(NullReturnType.Instance);
		}
		
		public override void OnSelfLiteralExpression(SelfLiteralExpression node)
		{
			if (callingClass == null)
				ClearResult();
			else
				MakeResult(callingClass.DefaultReturnType);
		}
		
		public override void OnSuperLiteralExpression(SuperLiteralExpression node)
		{
			if (callingClass == null)
				ClearResult();
			else
				MakeResult(callingClass.BaseType);
		}
		
		public override void OnSimpleTypeReference(SimpleTypeReference node)
		{
			MakeTypeResult(ConvertType(node));
		}
		
		public override void OnStringLiteralExpression(StringLiteralExpression node)
		{
			MakeResult(ReflectionReturnType.String);
		}
		
		public override void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node)
		{
			MakeLiteralResult("System.TimeSpan");
		}
		
		public override void OnTypeofExpression(TypeofExpression node)
		{
			MakeLiteralResult("System.Type");
		}
		
		IReturnType ConvertType(TypeReference typeRef)
		{
			return resolver.ConvertType(typeRef);
		}
	}
}

⌨️ 快捷键说明

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