Esempio n. 1
0
        public IDataFlowGraphOutput AddAssignment(VariableName name, IDataFlowGraphExpressionNode value)
        {
            var node = new AssignmentOutput(name, value, Guid.NewGuid());

            _outputs.Add(node);
            return(node);
        }
Esempio n. 2
0
        private AssignmentOutput Build(Expression expression)
        {
            if (expression is MemberExpression memberExpression)
            {
                var owner = memberExpression.Expression;
                AssignmentOutput ownerAssignment = null;
                if (owner == null)
                {
                    var memberDeclaringType = memberExpression.Member.DeclaringType;
                    var name = memberDeclaringType.Name;
                    ownerAssignment = new AssignmentOutput(name, name, memberDeclaringType, name);
                }
                else
                {
                    ownerAssignment = Build(memberExpression.Expression);
                }

                if (memberExpression.Member is PropertyInfo propertyInfo)
                {
                    var name     = propertyInfo.Name;
                    var fullName = $"{ownerAssignment.FullName}{propertyInfo.Name}";
                    return(new AssignmentOutput(name, fullName, propertyInfo.PropertyType,
                                                $"{ownerAssignment.Assignment}.{propertyInfo.Name}"));
                }
                if (memberExpression.Member is FieldInfo fieldInfo)
                {
                    var name     = fieldInfo.Name;
                    var fullName = $"{ownerAssignment.FullName}{fieldInfo.Name}";
                    return(new AssignmentOutput(name, fullName, fieldInfo.FieldType,
                                                $"{ownerAssignment.Assignment}.{fieldInfo.Name}"));
                }
            }
            if (expression is ParameterExpression parameterExpression)
            {
                return(new AssignmentOutput("this", "", parameterExpression.Type, "$this"));
            }
            if (expression is ConstantExpression constantExpression)
            {
                if (constantExpression.Value is string stringValue)
                {
                    return(new AssignmentOutput("const", "", constantExpression.Type, $"\"{stringValue}\""));
                }
                if (constantExpression.Value == null)
                {
                    return(new AssignmentOutput("const", "", constantExpression.Type, $"null"));
                }
                return(new AssignmentOutput("const", "", constantExpression.Type, $"\"{constantExpression.Value.ToString()}\""));
            }
            if (expression is MethodCallExpression methodCallExpression)
            {
                AssignmentOutput callerAssignment = null;
                var arguments = GetCsvList(methodCallExpression.Arguments.Select(a => Build(a).Assignment));

                // Non-static call
                if (methodCallExpression.Object != null)
                {
                    callerAssignment = Build(methodCallExpression.Object);
                }
                // Extension method call
                else if (methodCallExpression.Method.IsDefined(
                             typeof(System.Runtime.CompilerServices.ExtensionAttribute)))
                {
                    var argumentsList = new List <Expression>(methodCallExpression.Arguments);
                    var owner         = argumentsList[0];
                    argumentsList.RemoveAt(0);

                    arguments = GetCsvList(argumentsList.Select(a => Build(a).Assignment));

                    callerAssignment = Build(owner);
                }
                // Static method call
                else
                {
                    var methodDeclaringType = methodCallExpression.Method.DeclaringType;
                    var name = methodDeclaringType?.Name ?? "";
                    callerAssignment = new AssignmentOutput(name, name, methodDeclaringType, name);
                }

                var methodName = methodCallExpression.Method.Name;
                var assignment = $"{callerAssignment.Assignment}.{methodCallExpression.Method.Name}({arguments})";
                var fullName   = $"{callerAssignment.FullName}{methodCallExpression.Method.Name}";

                if (methodCallExpression.Method.IsSpecialName && methodName == "get_Item")
                {
                    assignment = $"{callerAssignment.Assignment}[{arguments}]";
                    fullName   = $"{callerAssignment.FullName}{arguments}";
                }

                return(new AssignmentOutput(methodName, fullName,
                                            methodCallExpression.Method.ReturnType, assignment));
            }
            if (expression is BinaryExpression binaryExpression)
            {
                var left     = Build(binaryExpression.Left);
                var type     = left.Type;
                var op       = "";
                var name     = "";
                var fullName = "";
                var right    = Build(binaryExpression.Right);
                switch (binaryExpression.NodeType)
                {
                case (ExpressionType.Coalesce):
                    op       = "??";
                    name     = left.Name;
                    fullName = left.FullName;
                    type     = Nullable.GetUnderlyingType(type) ?? type;
                    break;

                case (ExpressionType.Equal):
                    op       = "==";
                    name     = left.Name;
                    fullName = "";
                    break;

                case (ExpressionType.NotEqual):
                    op       = "!=";
                    name     = left.Name;
                    fullName = "";
                    break;

                default:
                    throw new NotSupportedException($"Binary Expression of type {binaryExpression.NodeType} is not supported yet");
                }

                return(new AssignmentOutput(name, fullName, type, $"{left.Assignment} {op} {right.Assignment}"));
            }
            if (expression is ConditionalExpression conditionalExpression)
            {
                var test    = Build(conditionalExpression.Test);
                var ifTrue  = Build(conditionalExpression.IfTrue);
                var ifFalse = Build(conditionalExpression.IfFalse);

                var name     = ifTrue.Name;
                var fullName = string.IsNullOrWhiteSpace(ifTrue.FullName) ? ifFalse.FullName : ifTrue.FullName;

                return(new AssignmentOutput(name, fullName, ifTrue.Type, $"{test.Assignment} ? {ifTrue.Assignment} : {ifFalse.Assignment}"));
            }

            throw new NotSupportedException($"Expression of type {expression.NodeType} is not supported yet");
        }