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

📄 convertvisitorexpressions.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: 1387 $</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 ConvertExpressions(IEnumerable input, B.ExpressionCollection output)
		{
			foreach (Expression e in input) {
				B.Expression expr = ConvertExpression(e);
				if (expr != null) {
					output.Add(expr);
				}
			}
		}
		
		B.Expression ConvertExpression(Expression expr)
		{
			if (expr.IsNull)
				return null;
			return (B.Expression)expr.AcceptVisitor(this, null);
		}
		
		B.Expression MakeReferenceExpression(TypeReference typeRef)
		{
			if (typeRef.IsArrayType)
				return new B.TypeofExpression(GetLexicalInfo(typeRef), ConvertTypeReference(typeRef));
			B.SimpleTypeReference t = (B.SimpleTypeReference)ConvertTypeReference(typeRef);
			B.ReferenceExpression r = MakeReferenceExpression(t.Name);
			if (t is B.GenericTypeReference) {
				B.GenericReferenceExpression gr = new B.GenericReferenceExpression(GetLexicalInfo(typeRef));
				gr.Target = r;
				foreach (B.TypeReference tr in ((B.GenericTypeReference)t).GenericArguments) {
					gr.GenericArguments.Add(tr);
				}
				return gr;
			} else {
				return r;
			}
		}
		
		B.ReferenceExpression MakeReferenceExpression(string fullName)
		{
			string[] parts = fullName.Split('.');
			B.ReferenceExpression r = new B.ReferenceExpression(lastLexicalInfo, parts[0]);
			for (int i = 1; i < parts.Length; i++)
				r = new B.MemberReferenceExpression(lastLexicalInfo, r, parts[i]);
			return r;
		}
		
		B.MethodInvocationExpression MakeMethodCall(string fullName, params B.Expression[] arguments)
		{
			return new B.MethodInvocationExpression(MakeReferenceExpression(fullName), arguments);
		}
		
		public object Visit(PrimitiveExpression pe, object data)
		{
			object val = pe.Value;
			if (val == null) {
				return new B.NullLiteralExpression(GetLexicalInfo(pe));
			}
			if (val is string) {
				return new B.StringLiteralExpression(GetLexicalInfo(pe), (string)val);
			}
			if (val is char) {
				return new B.CharLiteralExpression(GetLexicalInfo(pe), ((char)val).ToString());
			}
			if (val is bool) {
				return new B.BoolLiteralExpression(GetLexicalInfo(pe), (bool)val);
			}
			if (val is byte) {
				AddWarning(pe, "Converting byte literal to int literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (byte)val, false);
			}
			if (val is short) {
				AddWarning(pe, "Converting short literal to int literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (short)val, false);
			}
			if (val is int) {
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (int)val, false);
			}
			if (val is long) {
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (long)val, true);
			}
			if (val is sbyte) {
				AddWarning(pe, "Converting sbyte literal to int literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (sbyte)val, false);
			}
			if (val is ushort) {
				AddWarning(pe, "Converting ushort literal to int literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (ushort)val, false);
			}
			if (val is uint) {
				AddWarning(pe, "Converting uint literal to int/long literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (uint)val);
			}
			if (val is ulong) {
				AddWarning(pe, "Converting ulong literal to long literal");
				return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (long)((ulong)val), true);
			}
			if (val is float) {
				return new B.DoubleLiteralExpression(GetLexicalInfo(pe), (float)val, true);
			}
			if (val is double) {
				return new B.DoubleLiteralExpression(GetLexicalInfo(pe), (double)val, false);
			}
			if (val is decimal) {
				AddWarning(pe, "Converting decimal literal to double literal");
				return new B.DoubleLiteralExpression(GetLexicalInfo(pe), (double)(decimal)val);
			}
			AddError(pe, "Unknown primitive literal of type " + val.GetType().FullName);
			return null;
		}
		
		public object Visit(IdentifierExpression identifierExpression, object data)
		{
			return new B.ReferenceExpression(GetLexicalInfo(identifierExpression), identifierExpression.Identifier);
		}
		
		public object Visit(FieldReferenceExpression fre, object data)
		{
			B.Expression target = null;
			if (fre.TargetObject is TypeReferenceExpression) {
				// not typeof, so this is something like int.Parse() or Class<string>.StaticMethod
				TypeReference typeRef = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
				if (!typeRef.IsArrayType)
					target = MakeReferenceExpression(typeRef);
			}
			if (target == null) {
				target = (B.Expression)fre.TargetObject.AcceptVisitor(this, data);
				if (target == null) return null;
			}
			return new B.MemberReferenceExpression(GetLexicalInfo(fre), target, fre.FieldName);
		}
		
		public object Visit(ClassReferenceExpression classReferenceExpression, object data)
		{
			// VB's MyClass.Method references methods in the CURRENT class, ignoring overrides!!!
			// that is supported neither by C# nor Boo.
			// Most of the time, "Me"="self" should also do the job.
			AddWarning(classReferenceExpression, "Class reference is not supported, replaced with self reference.");
			return new B.SelfLiteralExpression(GetLexicalInfo(classReferenceExpression));
		}
		
		B.BinaryOperatorType ConvertOperator(AssignmentOperatorType op, out bool isInPlace)
		{
			isInPlace = true;
			switch (op) {
				case AssignmentOperatorType.Add:
					return B.BinaryOperatorType.InPlaceAddition;
				case AssignmentOperatorType.Assign:
					return B.BinaryOperatorType.Assign;
				case AssignmentOperatorType.BitwiseAnd:
					return B.BinaryOperatorType.InPlaceBitwiseAnd;
				case AssignmentOperatorType.BitwiseOr:
					return B.BinaryOperatorType.InPlaceBitwiseOr;
				case AssignmentOperatorType.ConcatString:
					return B.BinaryOperatorType.InPlaceAddition;
				case AssignmentOperatorType.Divide:
					return B.BinaryOperatorType.InPlaceDivision;
				case AssignmentOperatorType.DivideInteger:
					return B.BinaryOperatorType.InPlaceDivision;
				case AssignmentOperatorType.ExclusiveOr:
					return B.BinaryOperatorType.InPlaceExclusiveOr;
				case AssignmentOperatorType.Modulus:
					isInPlace = false;
					return B.BinaryOperatorType.Modulus;
				case AssignmentOperatorType.Multiply:
					return B.BinaryOperatorType.InPlaceMultiply;
				case AssignmentOperatorType.Power:
					isInPlace = false;
					return B.BinaryOperatorType.Exponentiation;
				case AssignmentOperatorType.ShiftLeft:
					return B.BinaryOperatorType.InPlaceShiftLeft;
				case AssignmentOperatorType.ShiftRight:
					return B.BinaryOperatorType.InPlaceShiftRight;
				case AssignmentOperatorType.Subtract:
					return B.BinaryOperatorType.InPlaceSubtraction;
				default:
					return B.BinaryOperatorType.None;
			}
		}
		
		public object Visit(AssignmentExpression assignmentExpression, object data)
		{
			B.Expression left = ConvertExpression(assignmentExpression.Left);
			B.Expression right = ConvertExpression(assignmentExpression.Right);
			bool isInPlace;
			B.BinaryOperatorType op = ConvertOperator(assignmentExpression.Op, out isInPlace);
			if (op == B.BinaryOperatorType.None) {
				AddError(assignmentExpression, "Unknown operator.");
				return null;
			}
			if (!isInPlace) {
				// convert L <OP>= R to L = L OP R
				right = new B.BinaryExpression(GetLexicalInfo(assignmentExpression), op, left, right);
				op = B.BinaryOperatorType.Assign;
			}
			return new B.BinaryExpression(GetLexicalInfo(assignmentExpression), op, left, right);
		}
		
		B.BinaryOperatorType ConvertOperator(BinaryOperatorType op)
		{
			switch (op) {
				case BinaryOperatorType.Add:
					return B.BinaryOperatorType.Addition;
				case BinaryOperatorType.BitwiseAnd:
					return B.BinaryOperatorType.BitwiseAnd;
				case BinaryOperatorType.BitwiseOr:
					return B.BinaryOperatorType.BitwiseOr;
				case BinaryOperatorType.Concat:
					return B.BinaryOperatorType.Addition;
				case BinaryOperatorType.Divide:
					return B.BinaryOperatorType.Division;
				case BinaryOperatorType.DivideInteger:
					return B.BinaryOperatorType.Division;
				case BinaryOperatorType.Equality:
					return B.BinaryOperatorType.Equality;
				case BinaryOperatorType.ExclusiveOr:
					return B.BinaryOperatorType.ExclusiveOr;
				case BinaryOperatorType.GreaterThan:
					return B.BinaryOperatorType.GreaterThan;
				case BinaryOperatorType.GreaterThanOrEqual:
					return B.BinaryOperatorType.GreaterThanOrEqual;
				case BinaryOperatorType.InEquality:
					return B.BinaryOperatorType.Inequality;
				case BinaryOperatorType.LessThan:
					return B.BinaryOperatorType.LessThan;
				case BinaryOperatorType.LessThanOrEqual:
					return B.BinaryOperatorType.LessThanOrEqual;
				case BinaryOperatorType.Like:
					return B.BinaryOperatorType.Match;
				case BinaryOperatorType.LogicalAnd:
					return B.BinaryOperatorType.And;
				case BinaryOperatorType.LogicalOr:
					return B.BinaryOperatorType.Or;
				case BinaryOperatorType.Modulus:
					return B.BinaryOperatorType.Modulus;
				case BinaryOperatorType.Multiply:
					return B.BinaryOperatorType.Multiply;
				case BinaryOperatorType.NullCoalescing:
					return B.BinaryOperatorType.Or;
				case BinaryOperatorType.Power:
					return B.BinaryOperatorType.Exponentiation;
				case BinaryOperatorType.ReferenceEquality:
					return B.BinaryOperatorType.ReferenceEquality;
				case BinaryOperatorType.ReferenceInequality:
					return B.BinaryOperatorType.ReferenceInequality;
				case BinaryOperatorType.ShiftLeft:
					return B.BinaryOperatorType.ShiftLeft;
				case BinaryOperatorType.ShiftRight:
					return B.BinaryOperatorType.ShiftRight;
				case BinaryOperatorType.Subtract:
					return B.BinaryOperatorType.Subtraction;
				default:
					return B.BinaryOperatorType.None;

⌨️ 快捷键说明

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