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

📄 inferredreturntype.cs

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

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

namespace Grunwald.BooBinding.CodeCompletion
{
	/// <summary>
	/// Return type that is inferred from an expression.
	/// </summary>
	public class InferredReturnType : ProxyReturnType
	{
		Expression expression;
		Block block;
		IReturnType cachedType;
		IClass context;
		
		public InferredReturnType(Expression expression, IClass context)
		{
			if (expression == null) throw new ArgumentNullException("expression");
			this.context = context;
			this.expression = expression;
		}
		
		bool useLastStatementIfNoReturnStatement;
		
		public InferredReturnType(Block block, IClass context, bool useLastStatementIfNoReturnStatement)
		{
			if (block == null) throw new ArgumentNullException("block");
			this.useLastStatementIfNoReturnStatement = useLastStatementIfNoReturnStatement;
			this.block = block;
			this.context = context;
		}
		
		public override IReturnType BaseType {
			get {
				// clear up references to method/expression after the type has been resolved
				if (block != null) {
					GetReturnTypeVisitor v = new GetReturnTypeVisitor(this);
					Block b = block;
					block = null; // reset block before calling Visit to prevent StackOverflow
					v.Visit(b);
					if (v.noReturnStatement) {
						if (useLastStatementIfNoReturnStatement && v.lastExpressionStatement != null) {
							cachedType = new BooResolver().GetTypeOfExpression(v.lastExpressionStatement.Expression, context);
						} else {
							cachedType = ReflectionReturnType.Void;
						}
					} else if (v.result is NullReturnType) {
						cachedType = ReflectionReturnType.Object;
					} else {
						cachedType = v.result;
					}
				} else if (expression != null) {
					Expression expr = expression;
					expression = null;
					cachedType = new BooResolver().GetTypeOfExpression(expr, context);
				}
				return cachedType;
			}
		}
		
		class GetReturnTypeVisitor : DepthFirstVisitor
		{
			IClass context;
			InferredReturnType parentReturnType;
			public GetReturnTypeVisitor(InferredReturnType parentReturnType)
			{
				this.context = parentReturnType.context;
				this.parentReturnType = parentReturnType;
			}
			
			public IReturnType result;
			public bool noReturnStatement = true;
			public ExpressionStatement lastExpressionStatement;
			
			public override void OnReturnStatement(ReturnStatement node)
			{
				noReturnStatement = false;
				if (node.Expression == null) {
					result = ReflectionReturnType.Void;
				} else {
					result = new BooResolver().GetTypeOfExpression(node.Expression, context);
				}
			}
			
			public override void OnExpressionStatement(ExpressionStatement node)
			{
				base.OnExpressionStatement(node);
				lastExpressionStatement = node;
			}
			
			public override void OnYieldStatement(YieldStatement node)
			{
				noReturnStatement = false;
				
				IProjectContent pc = context != null ? context.ProjectContent : ParserService.CurrentProjectContent;
				IReturnType enumerable = new GetClassReturnType(pc, "System.Collections.Generic.IEnumerable", 1);
				
				// Prevent creating an infinite number of InferredReturnTypes in inferring cycles
				parentReturnType.expression = new NullLiteralExpression();
				IReturnType returnType;
				if (node.Expression == null)
					returnType = ReflectionReturnType.Object;
				else
					returnType = new BooResolver().GetTypeOfExpression(node.Expression, context);
				if (returnType != null) {
					returnType.GetUnderlyingClass(); // force to infer type
				}
				if (parentReturnType.expression == null) {
					// inferrence cycle with parentReturnType
					returnType = new GetClassReturnType(context.ProjectContent, "?", 0);
				}
				parentReturnType.expression = null;
				
				result = new ConstructedReturnType(enumerable, new IReturnType[] { returnType });
			}
			
			public override void OnCallableBlockExpression(CallableBlockExpression node)
			{
				// ignore return statements in callable blocks
			}
			
			public override bool Visit(Node node)
			{
				if (result != null && !(result is NullReturnType))
					return false;
				else
					return base.Visit(node);
			}
		}
	}
}

⌨️ 快捷键说明

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