Exemplo n.º 1
0
        private void SolveConditionContexts(
            [NotNull] GraphDataFlowConditionalNode node,
            [NotNull] LogicExpressionBase expression,
            [NotNull] GraphNode[] path)
        {
            var trueChanges  = new List <(ValueVariantBase, IDataValue)>();
            var falseChanges = new List <(ValueVariantBase, IDataValue)>();

            if (!SolveExpression(node.EnterAnalysisContext, expression, trueChanges, falseChanges))
            {
                Log.Information("Logic: {Operator} -> {Expression}",
                                expression.Operator,
                                expression);
            }

            foreach (var grouping in trueChanges.GroupBy(x => x.Item1, x => x.Item2))
            {
                var(variant, dataValue) = (grouping.Key, grouping.ToArray());
                var newVariant = variant.Clone(node.EnterAnalysisContext, path);
                newVariant.Value = ValueUtilities.IterateValues(dataValue, variant.Value, dataValue.Length + 1,
                                                                ValueUtilities.IterateValuesAndFunc);
                node.TrueExitAnalysisContext[variant] = newVariant;
            }

            foreach (var grouping in falseChanges.GroupBy(x => x.Item1, x => x.Item2))
            {
                var(variant, dataValue) = (grouping.Key, grouping.ToArray());
                var newVariant = variant.Clone(node.EnterAnalysisContext, path);
                newVariant.Value = ValueUtilities.IterateValues(dataValue, variant.Value, dataValue.Length + 1,
                                                                ValueUtilities.IterateValuesAndFunc);
                node.FalseExitAnalysisContext[variant] = newVariant;
            }
        }
 private bool SolveExpression(
     [NotNull] AnalysisContext context,
     [NotNull] LogicExpressionBase logicExpressionBase,
     List <(ValueVariantBase, IDataValue)> trueChanges,
        public static ValueInterval ToInterval([NotNull] AnalysisContext context,
                                               [NotNull] LogicExpressionBase expression,
                                               [NotNull] ILValue lValue)
        {
            switch (expression)
            {
            case BinaryLogicExpression binaryLogicExpression:
                if (binaryLogicExpression.Left is OrderedLiteralBase && binaryLogicExpression.Right is Variable)
                {
                    binaryLogicExpression = binaryLogicExpression.Flip();
                }

                var left  = binaryLogicExpression.Left;
                var right = context[binaryLogicExpression.Right];
                if (right == null)
                {
                    return(null);
                }

                ILValue            variant = null;
                OrderedLiteralBase literal = null;
                switch (left)
                {
                case ILValue valueVariantBase:
                    variant = valueVariantBase;
                    break;

                case OrderedLiteralBase orderedLiteralBase:
                    literal = orderedLiteralBase;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(left));
                }

                switch (right)
                {
                case ILValue valueVariantBase:
                    variant = valueVariantBase;
                    break;

                case OrderedLiteralBase orderedLiteralBase:
                    literal = orderedLiteralBase;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(right));
                }

                if (variant == null || literal == null)
                {
                    return(null);
                }

                if (Equals(lValue, variant) ||
                    variant is IVariantWithStorageVariable variantWithStorage &&
                    Equals(variantWithStorage.StorageVariable, lValue))
                {
                    return(OperatorToInterval(binaryLogicExpression.Operator,
                                              literal,
                                              variant.TypeRef));
                }
                else
                {
                    return(null);
                }