📄 convertvisitorexpressions.cs
字号:
// <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 + -