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

📄 convertvisitorstatements.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: 1014 $</version>
// </file>

using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
using Boo.Lang.Compiler;
using B = Boo.Lang.Compiler.Ast;

namespace NRefactoryToBooConverter
{
	partial class ConvertVisitor
	{
		void ConvertStatements(IEnumerable statements, B.Block b)
		{
			foreach (Statement n in statements) {
				AddToBlock(n, b);
			}
		}
		
		Statement currentStatement;
		
		object ConvertStatementInternal(Statement stmt)
		{
			Statement oldStatement = currentStatement;
			currentStatement = stmt;
			try {
				return stmt.AcceptVisitor(this, null);
			} finally {
				currentStatement = oldStatement;
			}
		}
		
		void AddToBlock(Statement n, B.Block b)
		{
			object result = ConvertStatementInternal(n);
			if (result is ArrayList) {
				foreach (B.Statement stmt in (ArrayList)result) {
					b.Add(stmt);
				}
			} else {
				B.Statement stmt = (B.Statement)result;
				if (stmt != null) {
					b.Add(stmt);
				}
			}
		}
		
		ArrayList ConvertStatements(IEnumerable statements)
		{
			ArrayList r = new ArrayList();
			foreach (Statement n in statements) {
				object result = ConvertStatementInternal(n);
				if (result is ArrayList) {
					r.AddRange((ArrayList)result);
				} else if (result != null) {
					r.Add(result);
				}
			}
			return r;
		}
		
		B.Block ConvertBlock(Statement statement)
		{
			if (statement == null || statement.IsNull)
				return null;
			List<Statement> statements = new List<Statement>(1);
			statements.Add(statement);
			return ConvertBlock(statements);
		}
		
		B.Block ConvertBlock(BlockStatement block)
		{
			B.Block b = new B.Block(GetLexicalInfo(block));
			b.EndSourceLocation = GetLocation(block.EndLocation);
			ConvertStatements(block.Children, b);
			return b;
		}
		
		B.Block ConvertBlock(List<Statement> statements)
		{
			if (statements.Count == 1) {
				if (statements[0] is BlockStatement)
					return ConvertBlock(statements[0] as BlockStatement);
			}
			B.Block b = new B.Block();
			ConvertStatements(statements, b);
			return b;
		}
		
		public object Visit(BlockStatement blockStatement, object data)
		{
			return ConvertBlock(blockStatement);
		}
		
		B.MacroStatement CreateMacro(INode node, string name, Statement embedded, params Expression[] arguments)
		{
			B.MacroStatement macro = new B.MacroStatement(GetLexicalInfo(node));
			macro.Name = name;
			ConvertExpressions(arguments, macro.Arguments);
			if (embedded is BlockStatement) {
				macro.Block = ConvertBlock((BlockStatement)embedded);
			} else {
				macro.Block = new B.Block();
				macro.Block.Add((B.Statement)embedded.AcceptVisitor(this, null));
			}
			return macro;
		}
		
		public object Visit(FixedStatement fixedStatement, object data)
		{
			AddError(fixedStatement, "FixedStatement is not supported.");
			return null;
		}
		
		public object Visit(UnsafeStatement unsafeStatement, object data)
		{
			AddError(unsafeStatement, "UnsafeStatement is not supported.");
			return null;
		}
		
		public object Visit(CheckedStatement checkedStatement, object data)
		{
			return CreateMacro(checkedStatement, "checked", checkedStatement.Block);
		}
		
		public object Visit(UncheckedStatement uncheckedStatement, object data)
		{
			return CreateMacro(uncheckedStatement, "unchecked", uncheckedStatement.Block);
		}
		
		public object Visit(ExitStatement exitStatement, object data)
		{
			if (exitStatement.ExitType == ExitType.Function || exitStatement.ExitType == ExitType.Sub || exitStatement.ExitType == ExitType.Property) {
				AddWarning(exitStatement, "ExitStatement is converted to 'return'");
				return new B.ReturnStatement(GetLexicalInfo(exitStatement));
			} else {
				AddWarning(exitStatement, "ExitStatement is converted to 'break'");
				return new B.BreakStatement(GetLexicalInfo(exitStatement));
			}
		}
		
		/// <summary>
		/// Make a loop:
		/// $initializers
		/// goto converterGeneratedName#
		/// while true:
		///     $iterators
		///     :converterGeneratedName#
		///     break $conditionType $condition
		/// 	$body
		/// </summary>
		ArrayList MakeManualLoop(INode node, List<Statement> initializers, B.StatementModifierType conditionType, Expression condition, List<Statement> iterators, Statement body)
		{
			// we use this "while true" form because "continue" must not skip the iterator.
			
			ArrayList list = ConvertStatements(initializers);
			B.LabelStatement labelStatement = MakeLabel(GenerateName());
			B.GotoStatement gotoStatement = new B.GotoStatement();
			gotoStatement.Label = new B.ReferenceExpression(labelStatement.Name);
			list.Add(gotoStatement);
			
			B.WhileStatement w = new B.WhileStatement(GetLexicalInfo(node));
			w.Condition = new B.BoolLiteralExpression(true);
			list.Add(w);
			w.Block = ConvertBlock(iterators);
			B.BreakStatement breakStatement = new B.BreakStatement();
			breakStatement.Modifier = new B.StatementModifier(conditionType, ConvertExpression(condition));
			w.Block.Add(labelStatement);
			w.Block.Add(breakStatement);
			foreach (B.Statement st in ConvertBlock(body).Statements) {
				w.Block.Add(st);
			}
			return list;
		}
		
		ArrayList MakeManualLoop(ForNextStatement forNextStatement)
		{
			Expression var = new IdentifierExpression(forNextStatement.VariableName);
			List<Statement> initializers = new List<Statement>(1);
			initializers.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Assign, forNextStatement.Start)));
			List<Statement> iterators = new List<Statement>(1);
			Expression step = forNextStatement.Step;
			if (step == null || step.IsNull)
				step = new PrimitiveExpression(1, "1");
			iterators.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Add, step)));
			PrimitiveExpression stepPE = step as PrimitiveExpression;
			if (stepPE == null || !(stepPE.Value is int)) {
				AddError(forNextStatement, "Step must be an integer literal");
				return null;
			}
			BinaryOperatorType conditionOperator;
			if ((int)stepPE.Value < 0) {
				conditionOperator = BinaryOperatorType.GreaterThanOrEqual;// counting down
			} else {
				conditionOperator = BinaryOperatorType.LessThanOrEqual;// counting up
			}
			Expression condition = new BinaryOperatorExpression(var, conditionOperator, forNextStatement.End);
			return MakeManualLoop(forNextStatement, initializers, B.StatementModifierType.Unless, condition, iterators, forNextStatement.EmbeddedStatement);
		}
		
		public object Visit(ForNextStatement forNextStatement, object data)
		{
			if (forNextStatement.TypeReference.IsNull)
				return MakeManualLoop(forNextStatement);
			B.ForStatement fs = new B.ForStatement(GetLexicalInfo(forNextStatement));
			fs.Block = ConvertBlock(forNextStatement.EmbeddedStatement);
			fs.Declarations.Add(new B.Declaration(forNextStatement.VariableName, null));
			B.Expression start = ConvertExpression(forNextStatement.Start);
			Expression end = forNextStatement.End;
			if (forNextStatement.Step == null || forNextStatement.Step.IsNull) {
				// range only goes to end - 1, so increment end
				end = Expression.AddInteger(end, 1);
				fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end));
			} else {
				PrimitiveExpression stepPE = forNextStatement.Step as PrimitiveExpression;
				if (stepPE == null || !(stepPE.Value is int)) {
					AddError(forNextStatement, "Step must be an integer literal");
				} else {
					if ((int)stepPE.Value < 0)
						end = Expression.AddInteger(end, -1);
					else
						end = Expression.AddInteger(end, 1);
				}
				fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end), ConvertExpression(forNextStatement.Step));
			}
			return fs;
		}
		
		public object Visit(ForStatement forStatement, object data)
		{
			return MakeManualLoop(forStatement, forStatement.Initializers, B.StatementModifierType.Unless,
			                      forStatement.Condition, forStatement.Iterator, forStatement.EmbeddedStatement);
		}
		
		public object Visit(DoLoopStatement doLoopStatement, object data)
		{
			bool frontCondition = doLoopStatement.ConditionPosition != ConditionPosition.End;
			bool negateCondition = doLoopStatement.ConditionType == ConditionType.Until;
			if (frontCondition && negateCondition) {
				// VB: Do Unless * : ** : Loop
				B.UnlessStatement u = new B.UnlessStatement(GetLexicalInfo(doLoopStatement));
				u.Condition = ConvertExpression(doLoopStatement.Condition);
				u.Block = ConvertBlock(doLoopStatement.EmbeddedStatement);
				return u;
			}
			// While and Do loop
			B.WhileStatement w = new B.WhileStatement(GetLexicalInfo(doLoopStatement));
			if (frontCondition)
				w.Condition = ConvertExpression(doLoopStatement.Condition);
			else
				w.Condition = new B.BoolLiteralExpression(true);
			w.Block = ConvertBlock(doLoopStatement.EmbeddedStatement);
			if (!frontCondition) {
				B.BreakStatement breakStatement = new B.BreakStatement();
				breakStatement.Modifier = new B.StatementModifier(negateCondition ? B.StatementModifierType.If : B.StatementModifierType.Unless,
				                                                  ConvertExpression(doLoopStatement.Condition));
				w.Block.Add(breakStatement);
			}
			return w;
		}
		
		public object Visit(ForeachStatement foreachStatement, object data)
		{
			B.ForStatement fs = new B.ForStatement(GetLexicalInfo(foreachStatement));
			fs.EndSourceLocation = GetLocation(foreachStatement.EndLocation);
			fs.Iterator = ConvertExpression(foreachStatement.Expression);
			fs.Declarations.Add(new B.Declaration(foreachStatement.VariableName, ConvertTypeReference(foreachStatement.TypeReference)));
			fs.Block = ConvertBlock(foreachStatement.EmbeddedStatement);
			return fs;
		}
		
		public object Visit(AddHandlerStatement addHandlerStatement, object data)
		{
			B.Expression expr = new B.BinaryExpression(GetLexicalInfo(addHandlerStatement),
			                                           B.BinaryOperatorType.InPlaceAddition,
			                                           ConvertExpression(addHandlerStatement.EventExpression),
			                                           ConvertExpression(addHandlerStatement.HandlerExpression));
			return new B.ExpressionStatement(expr);
		}
		
		public object Visit(RemoveHandlerStatement removeHandlerStatement, object data)
		{
			B.Expression expr = new B.BinaryExpression(GetLexicalInfo(removeHandlerStatement),
			                                           B.BinaryOperatorType.InPlaceSubtraction,
			                                           ConvertExpression(removeHandlerStatement.EventExpression),
			                                           ConvertExpression(removeHandlerStatement.HandlerExpression));
			return new B.ExpressionStatement(expr);
		}
		
		public object Visit(RaiseEventStatement raiseEventStatement, object data)
		{
			B.MethodInvocationExpression mie = new B.MethodInvocationExpression(GetLexicalInfo(raiseEventStatement));
			mie.Target = new B.ReferenceExpression(raiseEventStatement.EventName);
			ConvertExpressions(raiseEventStatement.Arguments, mie.Arguments);
			return new B.ExpressionStatement(mie);
		}
		
		public object Visit(EraseStatement eraseStatement, object data)
		{
			ArrayList statements = new ArrayList();
			foreach (Expression expr in eraseStatement.Expressions) {
				B.Expression e = ConvertExpression(expr);
				e = new B.BinaryExpression(B.BinaryOperatorType.Assign, e, new B.NullLiteralExpression());
				statements.Add(new B.ExpressionStatement(e));
			}
			return statements;
		}
		
		public object Visit(ReDimStatement reDimStatement, object data)
		{
			// Redim [Preserve] a(newBounds)
			// without preserve:
			//    a = array(Type, newBounds)
			// with preserve:
			//    ??1 = array(Type, newBounds)
			//    Array.Copy(a, ??1, System.Math.Min(a.Length, ??1.Length))
			//    a = ??1
			if (reDimStatement.IsPreserve)
				AddError(reDimStatement, "Redim Preserve is not supported.");
			ArrayList list = new ArrayList();
			foreach (InvocationExpression o in reDimStatement.ReDimClauses) {
				if (o.TypeArguments != null && o.TypeArguments.Count > 0) {
					AddError(o, "Type parameter are not allowed here.");
				}
				IdentifierExpression identifier = o.TargetObject as IdentifierExpression;
				if (identifier == null) {
					AddError(o, "Sorry, that expression is too complex to be resolved by the converter.");
				} else {
					// first we need to find out the array type
					VariableResolver resolver = new VariableResolver(nameComparer);
					TypeReference r = resolver.FindType(identifier.Identifier, reDimStatement);
					if (r == null) {
						AddError(o, "The name '" + identifier.Identifier + "' could not be resolved by the converter.");
					} else if (!r.IsArrayType) {
						AddError(o, identifier.Identifier + " is not an array.");
					} else {

⌨️ 快捷键说明

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