private InvocationExpressionBuilder MakeRoundingExpression(ExpressionBuilder inner, ConstantExpressionBuilder decimals, MemberExpressionBuilder direction) { if (direction != null) { string roundingFunction; if (direction.IsEquivalent("BigDecimal.ROUND_UP")) { roundingFunction = "Ceiling"; } else if (direction.IsEquivalent("BigDecimal.ROUND_DOWN")) { roundingFunction = "Floor"; } else { throw new NotSupportedException(); } var invocation = new InvocationExpressionBuilder(roundingFunction); invocation.Arguments.Add(inner); invocation.Arguments.Add(decimals); return(invocation); } else { var invocation = new InvocationExpressionBuilder("System.Math.Round"); invocation.Arguments.Add(inner); invocation.Arguments.Add(decimals); invocation.Arguments.Add(new MemberExpressionBuilder("System", "MidpointRounding", "AwayFromZero")); return(invocation); } }
public override void VisitInvocationExpression(InvocationExpressionSyntax node) { var memberAccessNode = (MemberAccessNode)Convert(node.Expression); var arguments = node.ArgumentList.Arguments.ToArray(); switch (memberAccessNode.MemberName) { case "setScale": { // Runden; erstes Argument ist Nachkommastelle, zweites Argument // ist Rundungsrichtung if (arguments.Length < 1 || arguments.Length > 2) { throw new NotSupportedException(); } var decimals = (ConstantExpressionBuilder)ConvertToExpression(arguments[0]); var direction = arguments.Length == 2 ? (MemberExpressionBuilder)((MemberAccessNode)Convert(arguments[1])).ToExpression() : null; Result = MakeRoundingExpression(memberAccessNode.BaseExpression, decimals, direction); break; } case "multiply": if (arguments.Length != 1) { throw new NotSupportedException(); } Result = new BinaryExpressionBuilder("*", memberAccessNode.BaseExpression, ConvertToExpression(arguments[0])); break; case "divide": if (arguments.Length == 3) { // divide(operand, nachkommastellen, rundungsrichtung) var operand = ConvertToExpression(arguments[0]); var decimals = (ConstantExpressionBuilder)ConvertToExpression(arguments[1]); var direction = (MemberExpressionBuilder)((MemberAccessNode)Convert(arguments[2])).ToExpression(); var division = new BinaryExpressionBuilder("/", memberAccessNode.BaseExpression, operand); Result = MakeRoundingExpression(division, decimals, direction); } else if (arguments.Length == 1) { Result = new BinaryExpressionBuilder("/", memberAccessNode.BaseExpression, ConvertToExpression(arguments[0])); } else { throw new NotSupportedException(); } break; case "add": if (arguments.Length != 1) { throw new NotSupportedException(); } Result = new BinaryExpressionBuilder("+", memberAccessNode.BaseExpression, ConvertToExpression(arguments[0])); break; case "subtract": if (arguments.Length != 1) { throw new NotSupportedException(); } Result = new BinaryExpressionBuilder("-", memberAccessNode.BaseExpression, ConvertToExpression(arguments[0])); break; case "compareTo": { if (arguments.Length != 1) { throw new NotSupportedException(); } var invocation = new InvocationExpressionBuilder("CompareTo"); invocation.Arguments.Add(memberAccessNode.BaseExpression); invocation.Arguments.Add(ConvertToExpression(arguments[0])); Result = invocation; break; } case "valueOf": // BigDecimal.valueOf if (arguments.Length != 1) { throw new NotSupportedException(); } if (!((MemberExpressionBuilder)memberAccessNode.BaseExpression).IsEquivalent("BigDecimal")) { throw new NotSupportedException(); } var innerExpression = ConvertToExpression(arguments[0]); var innerConst = innerExpression as ConstantExpressionBuilder; if (innerConst != null) { // Der innere Ausdruck ist eine Konstante, wir ändern den gesamten Ausdruck in // eine decimal-Konstante Result = new ConstantExpressionBuilder(typeof(decimal), innerConst.TextConstant); } else { // Der innere Ausdruck ist irgendetwas anderes, wir casten ihn nach decimal Result = new CastExpressionBuilder(typeof(decimal), innerExpression); } break; case "longValue": if (arguments.Length != 0) { throw new NotSupportedException(); } Result = new CastExpressionBuilder(typeof(long), memberAccessNode.BaseExpression); break; default: throw new NotSupportedException(); } }