Ejemplo n.º 1
0
 static string OutermostValue(ExpressionToCodeConfiguration config, StringifiedExpression node)
 {
     if (node.OptionalValue != null)
     {
         return(ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue, 10));
     }
     foreach (var kid in node.Children)
     {
         if (!kid.IsConceptualChild)
         {
             var value = OutermostValue(config, kid);
             if (value != null)
             {
                 return(value);
             }
         }
     }
     foreach (var kid in node.Children)
     {
         if (kid.IsConceptualChild)
         {
             var value = OutermostValue(config, kid);
             if (value != null)
             {
                 return(value);
             }
         }
     }
     return(null);
 }
 public static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object val, int indent)
 {
     string retval = ObjectToCode.PlainObjectToCode(val);
     if (retval != null) {
         return retval;
     } else if (val is Array) {
         return "new[] " + FormatEnumerable(config, (IEnumerable)val, indent);
     } else if (val is IEnumerable) {
         return FormatEnumerable(config, (IEnumerable)val, indent);
     } else if (val is Expression) {
         return config.GetExpressionToCode().ToCode((Expression)val);
     } else if (val.GetType().GuessTypeClass() == ReflectionHelpers.TypeClass.AnonymousType) {
         var type = val.GetType();
         return "new {" +
             string.Join(
                 "",
                 type.GetProperties()
                     .Select(
                         pi =>
                             "\n" + new string(' ', indent * 2 + 2) + pi.Name + " = "
                                 + ComplexObjectToPseudoCode(config, pi.GetValue(val, null), indent + 2) + ",")
                 )
             + "\n" + new string(' ', indent * 2) + "}";
     } else {
         return val.ToString();
     }
 }
Ejemplo n.º 3
0
        static void AppendTo(
            ExpressionToCodeConfiguration config,
            StringBuilder sb,
            List <SubExpressionInfo> nodeInfos,
            StringifiedExpression node,
            ref bool ignoreInitialSpace,
            bool showTopExpressionValue)
        {
            if (node.Text != null)
            {
                var trimmedText = ignoreInitialSpace ? node.Text.TrimStart() : node.Text;
                var pos0        = sb.Length;
                sb.Append(trimmedText);
                ignoreInitialSpace = node.Text.Any() && ExpressionToCode.ShouldIgnoreSpaceAfter(node.Text[node.Text.Length - 1]);
                if (showTopExpressionValue)
                {
                    var valueString = node.OptionalValue == null ? null : ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue, 0);
                    if (valueString != null)
                    {
                        nodeInfos.Add(new SubExpressionInfo {
                            Location = pos0 + trimmedText.Length / 2, Value = valueString
                        });
                    }
                }
            }

            foreach (var kid in node.Children)
            {
                AppendTo(config, sb, nodeInfos, kid, ref ignoreInitialSpace, showTopExpressionValue || kid.IsConceptualChild);
            }
        }
        public string AnnotateExpressionTree(ExpressionToCodeConfiguration config, Expression expr, string msg, bool hideOutermostValue)
        {
            var splitLine = ExpressionToStringWithValues(config, expr, hideOutermostValue);

            var exprWithStalkedValues = new StringBuilder();
            if (msg == null) {
                exprWithStalkedValues.AppendLine(splitLine.Line);
            } else if (IsMultiline(msg)) {
                exprWithStalkedValues.AppendLine(msg);
                exprWithStalkedValues.AppendLine(splitLine.Line);
            } else {
                exprWithStalkedValues.AppendLine(splitLine.Line + "  :  " + msg);
            }

            for (int nodeI = splitLine.Nodes.Length - 1; nodeI >= 0; nodeI--) {
                char[] stalkLine = new string('\u2007', splitLine.Nodes[nodeI].Location).ToCharArray(); //figure-spaces.
                for (int i = 0; i < stalkLine.Length; i++) {
                    if (splitLine.Line[i] == ' ') {
                        stalkLine[i] = ' '; //use normal spaces where the expr used normal spaces for more natural spacing.
                    }
                }

                for (int prevI = 0; prevI < nodeI; prevI++) {
                    stalkLine[splitLine.Nodes[prevI].Location] = '\u2502'; //light vertical lines
                }
                exprWithStalkedValues.AppendLine((new string(stalkLine) + splitLine.Nodes[nodeI].Value).TrimEnd());
            }

            return exprWithStalkedValues.ToString();
        }
 static bool?EvalBoolExpr(ExpressionToCodeConfiguration config, Expression e)
 {
     try {
         return(EvalBoolLambda(config, Expression.Lambda <Func <bool> >(e)));
     } catch (InvalidCastException) {
         return(null);
     }
 }
 public static string ToCodeString(ExpressionToCodeConfiguration config, Expression e)
 {
     var sb = new StringBuilder();
     var ignoreInitialSpace = true;
     var stringifiedExpr = new ExpressionToCodeImpl(config).ExpressionDispatch(e);
     AppendTo(sb, ref ignoreInitialSpace, stringifiedExpr);
     return sb.ToString();
 }
 static bool?EvalBoolLambda(ExpressionToCodeConfiguration config, Expression <Func <bool> > e)
 {
     try {
         return(EvalBoolFunc(config.Value.ExpressionCompiler.Compile(e)));
     } catch (InvalidOperationException) {
         return(null);
     }
 }
Ejemplo n.º 8
0
        public static string ToCodeString(ExpressionToCodeConfiguration config, Expression e)
        {
            var sb = new StringBuilder();
            var ignoreInitialSpace = true;
            var stringifiedExpr    = new ExpressionToCodeImpl(config).ExpressionDispatch(e);

            AppendTo(sb, ref ignoreInitialSpace, stringifiedExpr);
            return(sb.ToString());
        }
 static SplitExpressionLine ExpressionToStringWithValues(ExpressionToCodeConfiguration config, Expression e, bool hideOutermostValue)
 {
     var nodeInfos = new List<SubExpressionInfo>();
     var sb = new StringBuilder();
     bool ignoreInitialSpace = true;
     var node = new ExpressionToCodeImpl(config).ExpressionDispatch(e);
     AppendTo(config, sb, nodeInfos, node, ref ignoreInitialSpace, !hideOutermostValue);
     nodeInfos.Add(new SubExpressionInfo { Location = sb.Length, Value = null });
     return new SplitExpressionLine { Line = sb.ToString().TrimEnd(), Nodes = nodeInfos.ToArray() };
 }
 public static ExpressionWithSubExpressions Create(ExpressionToCodeConfiguration config, Expression e, bool hideOutermostValue)
 {
     var sb = new StringBuilder();
     bool ignoreInitialSpace = true;
     var node = new ExpressionToCodeImpl(config).ExpressionDispatch(e);
     AppendNodeToStringBuilder(sb, node, ref ignoreInitialSpace);
     var fullExprText = sb.ToString();
     var subExpressionValues = new List<SubExpressionValue>();
     FindSubExpressionValues(config, node, node, subExpressionValues, hideOutermostValue);
     return new ExpressionWithSubExpressions { ExpressionString = fullExprText, SubExpressions = subExpressionValues.ToArray() };
 }
 static string FormatEnumerable(ExpressionToCodeConfiguration config, IEnumerable list, int indent)
 {
     var contents = PrintListContents(config, list, indent).ToArray();
     if (contents.Sum(s => s.Length) > 100 || contents.Any(s => s.Any(c => c == '\n'))) {
         var indentString = new string(' ', indent * 2 + 2);
         return "{\n"
             + string.Join("", contents.Select(s => indentString + s + (s == "..." ? "" : ",") + "\n"))
             + new string(' ', indent * 2)
             + "}";
     }
     return "{" + string.Join(", ", contents) + "}";
 }
 static IEnumerable<string> PrintListContents(ExpressionToCodeConfiguration config, IEnumerable list, int indent)
 {
     int count = 0;
     foreach (var item in list) {
         count++;
         if (count > config.Value.PrintedListLengthLimit) {
             yield return "...";
             yield break;
         } else {
             yield return ComplexObjectToPseudoCode(config, item, indent + 4);
         }
     }
 }
Ejemplo n.º 13
0
        static string FormatEnumerable(ExpressionToCodeConfiguration config, IEnumerable list, int indent, int valueSize)
        {
            var contents = PrintListContents(config, list, indent).ToArray();

            if (contents.Sum(s => s.Length + 2) > Math.Min(valueSize, 120) || contents.Any(s => s.Any(c => c == '\n')))
            {
                return("{"
                       + string.Join("", contents.Select(s => ElidePossiblyMultilineString(config, s, indent + 4, valueSize - 3) + (s == "..." ? "" : ",")))
                       + "\n" + new string(' ', indent)
                       + "}");
            }
            return("{" + string.Join(", ", contents) + "}");
        }
 static ConstantExpression ToConstantExpr(ExpressionToCodeConfiguration config, Expression e)
 {
     try {
         var func = config.Value.ExpressionCompiler.Compile(Expression.Lambda(e));
         try {
             var val = func.DynamicInvoke();
             return(Expression.Constant(val, e.Type));
         } catch (Exception) {
             return(null); //todo:more specific?
         }
     } catch (InvalidOperationException) {
         return(null);
     }
 }
Ejemplo n.º 15
0
        static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object?val, int indent, int valueSize)
        {
            var retval = ObjectToCode.PlainObjectToCode(val);

            if (val is string)
            {
                return(ElidePossiblyMultilineString(config, retval ?? throw new InvalidOperationException("retval cannot be null for strings"), indent, valueSize).Trim());
            }
            else if (retval != null)
            {
                return(ElideAfter(retval, valueSize));
            }
            else if (val == null)
            {
                throw new Exception("Impossible: if val is null, retval cannot be");
            }
            else if (val is Array arrayVal)
            {
                return("new[] " + FormatEnumerable(config, arrayVal, indent, valueSize - 6));
            }
            else if (val is IEnumerable enumerableVal)
            {
                return(FormatTypeWithListInitializerOrNull(config, val, indent, valueSize, enumerableVal) ?? FormatEnumerable(config, enumerableVal, indent, valueSize));
            }
            else if (val is Expression exprVal)
            {
                return(ElideAfter(config.GetExpressionToCode().ToCode(exprVal), valueSize));
            }
            else if (val is IStructuralComparable tuple && val is IComparable && CSharpFriendlyTypeName.IsValueTupleType(val.GetType().GetTypeInfo()))
            {
                var collector = new NastyHackyTupleCollector();
                tuple.CompareTo(tuple, collector);
                var sb = new StringBuilder();
                sb.Append("(");
                for (var index = 0; index < collector.CollectedObjects.Count; index++)
                {
                    var item     = collector.CollectedObjects[index];
                    var asString = ComplexObjectToPseudoCode(config, item, indent + 4, valueSize);
                    if (index > 0)
                    {
                        sb.Append(", ");
                    }

                    sb.Append(asString);
                }

                sb.Append(")");
                return(ElidePossiblyMultilineString(config, sb.ToString(), indent, valueSize).Trim());
            }
            public static ExpressionWithSubExpressions Create(ExpressionToCodeConfiguration config, Expression e, bool hideOutermostValue)
            {
                var sb = new StringBuilder();
                var ignoreInitialSpace = true;
                var node = new ExpressionToCodeImpl(config).ExpressionDispatch(e);

                AppendNodeToStringBuilder(sb, node, ref ignoreInitialSpace);
                var fullExprText        = sb.ToString();
                var subExpressionValues = new List <SubExpressionValue>();

                FindSubExpressionValues(config, node, node, subExpressionValues, hideOutermostValue);
                return(new ExpressionWithSubExpressions {
                    ExpressionString = fullExprText, SubExpressions = subExpressionValues.Distinct().ToArray()
                });
            }
Ejemplo n.º 17
0
        static SplitExpressionLine ExpressionToStringWithValues(ExpressionToCodeConfiguration config, Expression e, bool outerValueIsAssertionFailure)
        {
            var nodeInfos          = new List <SubExpressionInfo>();
            var sb                 = new StringBuilder();
            var ignoreInitialSpace = true;
            var node               = new ExpressionToCodeImpl(config).ExpressionDispatch(e);

            AppendTo(config, sb, nodeInfos, node, ref ignoreInitialSpace, !outerValueIsAssertionFailure);
            nodeInfos.Add(new SubExpressionInfo {
                Location = sb.Length, Value = null
            });
            return(new SplitExpressionLine {
                Line = sb.ToString().TrimEnd(), Nodes = nodeInfos.ToArray()
            });
        }
 static void AppendTo(ExpressionToCodeConfiguration config, StringBuilder sb, List<SubExpressionInfo> nodeInfos, StringifiedExpression node, ref bool ignoreInitialSpace, bool showTopExpressionValue)
 {
     if (node.Text != null) {
         var trimmedText = ignoreInitialSpace ? node.Text.TrimStart() : node.Text;
         var pos0 = sb.Length;
         sb.Append(trimmedText);
         ignoreInitialSpace = node.Text.Any() && ExpressionToCode.ShouldIgnoreSpaceAfter(node.Text[node.Text.Length - 1]);
         if (showTopExpressionValue) {
             string valueString = node.OptionalValue == null ? null : ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue);
             if (valueString != null) {
                 nodeInfos.Add(new SubExpressionInfo { Location = pos0 + trimmedText.Length / 2, Value = valueString });
             }
         }
     }
     foreach (var kid in node.Children) {
         AppendTo(config, sb, nodeInfos, kid, ref ignoreInitialSpace, showTopExpressionValue || kid.IsConceptualChild);
     }
 }
Ejemplo n.º 19
0
        static string ElidePossiblyMultilineString(ExpressionToCodeConfiguration config, string val, int indent, int len)
        {
            var lines        = val.Split(lineSeparators, StringSplitOptions.None);
            var indentString = new string(' ', indent);

            if (lines.Length < 2)
            {
                return("\n" + indentString + ElideAfter(val, len));
            }
            if (config.Value.PrintedListLengthLimit is int limit && lines.Length > limit)
            {
                lines = lines.Take(limit).Concat(new[] { "..." }).ToArray();
            }
            var stringBoundaryPrefix = lines[0].StartsWith("@\"") ? 2 : lines[0].StartsWith("\"") ? 1 : 0;
            var firstLineIndent      = "\n" + indentString.Substring(0, Math.Max(0, indentString.Length - stringBoundaryPrefix));

            return(firstLineIndent + string.Join("\n" + indentString, lines.Select(s => ElideAfter(s, len - 1))));
        }
Ejemplo n.º 20
0
        static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object val, int indent, int valueSize)
        {
            var retval = ObjectToCode.PlainObjectToCode(val);

            if (val is string)
            {
                return(ElidePossiblyMultilineString(config, retval, indent, valueSize).Trim());
            }
            else if (retval != null)
            {
                return(ElideAfter(retval, valueSize));
            }
            else if (val is Array)
            {
                return("new[] " + FormatEnumerable(config, (IEnumerable)val, indent, valueSize - 6));
            }
            else if (val is IEnumerable)
            {
                return(FormatEnumerable(config, (IEnumerable)val, indent, valueSize));
            }
            else if (val is Expression)
            {
                return(ElideAfter(config.GetExpressionToCode().ToCode((Expression)val), valueSize));
            }
            else if (val.GetType().GuessTypeClass() == ReflectionHelpers.TypeClass.AnonymousType)
            {
                var type = val.GetType();
                return("new {" +
                       string.Join(
                           "",
                           type.GetTypeInfo()
                           .GetProperties()
                           .Select(
                               pi =>
                               "\n" + new string(' ', indent + 4) + pi.Name + " = "
                               + ComplexObjectToPseudoCode(config, pi.GetValue(val, null), indent + 4, valueSize - pi.Name.Length) + ",")
                           )
                       + "\n" + new string(' ', indent) + "}");
            }
            else
            {
                return(ElideAfter(val.ToString(), valueSize));
            }
        }
Ejemplo n.º 21
0
            static void FindSubExpressionValues(
                ExpressionToCodeConfiguration config,
                StringifiedExpression node,
                StringifiedExpression subExprNode,
                List <SubExpressionValue> subExpressionValues,
                bool outerValueIsAssertionFailure)
            {
                if (!outerValueIsAssertionFailure && node.OptionalValue != null)
                {
                    var sb = new StringBuilder();
                    var ignoreInitialSpace = true;
                    var valueString        = ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue, 10);
                    AppendNodeToStringBuilder(sb, subExprNode, ref ignoreInitialSpace);
                    var maxSize       = Math.Max(40, config.Value.MaximumValueLength ?? 200);
                    var subExprString = sb.Length <= maxSize
                        ? sb.ToString()
                        : sb.ToString(0, maxSize / 2 - 1) + "  …  " + sb.ToString(sb.Length - (maxSize / 2 - 1), maxSize / 2 - 1);

                    // ReSharper disable once ReplaceWithStringIsNullOrEmpty - for nullability analysis
                    if (valueString != null && valueString != "")
                    {
                        subExpressionValues.Add(new SubExpressionValue {
                            SubExpression = subExprString, ValueAsString = valueString
                        });
                    }
                }

                foreach (var kid in node.Children)
                {
                    if (!kid.IsConceptualChild)
                    {
                        FindSubExpressionValues(config, kid, subExprNode, subExpressionValues, outerValueIsAssertionFailure);
                    }
                }

                foreach (var kid in node.Children)
                {
                    if (kid.IsConceptualChild)
                    {
                        FindSubExpressionValues(config, kid, kid, subExpressionValues, false);
                    }
                }
            }
Ejemplo n.º 22
0
            public static ExpressionWithSubExpressions Create(ExpressionToCodeConfiguration config, Expression e, bool outerValueIsAssertionFailure)
            {
                var sb = new StringBuilder();
                var ignoreInitialSpace = true;
                var node = new ExpressionToCodeImpl(config).ExpressionDispatch(e);

                AppendNodeToStringBuilder(sb, node, ref ignoreInitialSpace);
                var fullExprText        = sb.ToString();
                var subExpressionValues = new List <SubExpressionValue>();

                FindSubExpressionValues(config, node, node, subExpressionValues, outerValueIsAssertionFailure);
                var assertionValue = outerValueIsAssertionFailure? OutermostValue(config, node) : null;

                return(new ExpressionWithSubExpressions {
                    ExpressionString = fullExprText
                                       + (assertionValue != null ? "\n" + spacedArrow + assertionValue + " (caused assertion failure)\n" :""),
                    SubExpressions = subExpressionValues.Distinct().ToArray()
                });
            }
Ejemplo n.º 23
0
            static IEnumerable <string> PrintInitializerContents(ExpressionToCodeConfiguration config, IEnumerable <KeyValuePair <TKey, TValue> > list)
            {
                var count = 0;

                foreach (var item in list)
                {
                    count++;
                    if (count > config.Value.PrintedListLengthLimit)
                    {
                        yield return("...");

                        yield break;
                    }
                    else
                    {
                        yield return($"[{ComplexObjectToPseudoCode(config, item.Key, 0)}] = {ComplexObjectToPseudoCode(config, item.Value, 0)}");
                    }
                }
            }
Ejemplo n.º 24
0
        static IEnumerable <string> PrintListContents(ExpressionToCodeConfiguration config, IEnumerable list, int indent)
        {
            var count = 0;

            foreach (var item in list)
            {
                count++;
                if (count > config.Value.PrintedListLengthLimit)
                {
                    yield return("...");

                    yield break;
                }
                else
                {
                    yield return(ComplexObjectToPseudoCode(config, item, 0));
                }
            }
        }
Ejemplo n.º 25
0
        public static string ExpressionValueAsCode(ExpressionToCodeConfiguration config, Expression expression, int indent)
        {
            try {
                Delegate lambda;
                try {
                    lambda = config.Value.ExpressionCompiler.Compile(Expression.Lambda(expression));
                } catch (InvalidOperationException) {
                    return(null);
                }

                var val = lambda.DynamicInvoke();
                try {
                    return(ComplexObjectToPseudoCode(config, val, indent));
                } catch (Exception e) {
                    return("stringification throws " + e.GetType().FullName);
                }
            } catch (TargetInvocationException tie) {
                return("throws " + tie.InnerException.GetType().FullName);
            }
        }
        public static string ExpressionValueAsCode(ExpressionToCodeConfiguration config, Expression expression)
        {
            try {
                Delegate lambda;
                try {
                    lambda = Expression.Lambda(expression).Compile();
                } catch (InvalidOperationException) {
                    return null;
                }

                var val = lambda.DynamicInvoke();
                try {
                    return ObjectToCodeImpl.ComplexObjectToPseudoCode(config, val, 0);
                } catch (Exception e) {
                    return "stringification throws " + e.GetType().FullName;
                }
            } catch (TargetInvocationException tie) {
                return "throws " + tie.InnerException.GetType().FullName;
            }
        }
Ejemplo n.º 27
0
        public string AnnotateExpressionTree(ExpressionToCodeConfiguration config, Expression expr, string?msg, bool outerValueIsAssertionFailure)
        {
            var splitLine = ExpressionToStringWithValues(config, expr, outerValueIsAssertionFailure);

            var exprWithStalkedValues = new StringBuilder();

            if (msg == null)
            {
                exprWithStalkedValues.AppendLine(splitLine.Line);
            }
            else if (IsMultiline(msg))
            {
                exprWithStalkedValues.AppendLine(msg);
                exprWithStalkedValues.AppendLine(splitLine.Line);
            }
            else
            {
                exprWithStalkedValues.AppendLine(splitLine.Line + "  :  " + msg);
            }

            for (var nodeI = splitLine.Nodes.Length - 1; nodeI >= 0; nodeI--)
            {
                var stalkLine = new string('\u2007', splitLine.Nodes[nodeI].Location).ToCharArray(); //figure-spaces.
                for (var i = 0; i < stalkLine.Length; i++)
                {
                    if (splitLine.Line[i] == ' ')
                    {
                        stalkLine[i] = ' '; //use normal spaces where the expr used normal spaces for more natural spacing.
                    }
                }

                for (var prevI = 0; prevI < nodeI; prevI++)
                {
                    stalkLine[splitLine.Nodes[prevI].Location] = '\u2502'; //light vertical lines
                }

                exprWithStalkedValues.AppendLine((new string(stalkLine) + splitLine.Nodes[nodeI].Value).TrimEnd());
            }

            return(exprWithStalkedValues.ToString());
        }
Ejemplo n.º 28
0
            static void FindSubExpressionValues(
                ExpressionToCodeConfiguration config,
                StringifiedExpression node,
                StringifiedExpression subExprNode,
                List <SubExpressionValue> subExpressionValues,
                bool hideOutermostValue)
            {
                if (!hideOutermostValue && node.OptionalValue != null)
                {
                    var sb = new StringBuilder();
                    var ignoreInitialSpace = true;
                    var valueString        = ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue, 10);
                    AppendNodeToStringBuilder(sb, subExprNode, ref ignoreInitialSpace);
                    var maxSize       = 80;
                    var subExprString = sb.Length <= maxSize
                        ? sb.ToString()
                        : sb.ToString(0, maxSize / 2 - 1) + "  …  " + sb.ToString(sb.Length - (maxSize / 2 - 1), maxSize / 2 - 1);

                    if (!string.IsNullOrEmpty(valueString))
                    {
                        subExpressionValues.Add(new SubExpressionValue {
                            SubExpression = subExprString, ValueAsString = valueString
                        });
                    }
                }
                foreach (var kid in node.Children)
                {
                    if (kid.IsConceptualChild)
                    {
                        FindSubExpressionValues(config, kid, kid, subExpressionValues, false);
                    }
                }
                foreach (var kid in node.Children)
                {
                    if (!kid.IsConceptualChild)
                    {
                        FindSubExpressionValues(config, kid, subExprNode, subExpressionValues, hideOutermostValue);
                    }
                }
            }
 static void FindSubExpressionValues(
     ExpressionToCodeConfiguration config,
     StringifiedExpression node,
     StringifiedExpression subExprNode,
     List<SubExpressionValue> subExpressionValues,
     bool hideOutermostValue)
 {
     if (!hideOutermostValue && node.OptionalValue != null) {
         var sb = new StringBuilder();
         var ignoreInitialSpace = true;
         AppendNodeWithLimitedDepth(sb, subExprNode, ref ignoreInitialSpace, 2);
         var subExprString = sb.ToString();
         string valueString = ObjectToCodeImpl.ExpressionValueAsCode(config, node.OptionalValue);
         subExpressionValues.Add(new SubExpressionValue { SubExpression = subExprString, ValueAsString = valueString });
     }
     foreach (var kid in node.Children) {
         if (kid.IsConceptualChild) {
             FindSubExpressionValues(config, kid, kid, subExpressionValues, false);
         } else {
             FindSubExpressionValues(config, kid, subExprNode, subExpressionValues, hideOutermostValue);
         }
     }
 }
Ejemplo n.º 30
0
 public string AnnotateExpressionTree(ExpressionToCodeConfiguration config, Expression expr, string msg, bool outerValueIsAssertionFailure)
 => (msg == null ? "" : msg + "\n\n") + ExpressionWithSubExpressions.Create(config, expr, outerValueIsAssertionFailure).ComposeToSingleString();
 public string AnnotateExpressionTree(ExpressionToCodeConfiguration config, Expression expr, string msg, bool hideOutermostValue)
 {
     return (msg == null ? "" : msg + "\n") + ExpressionWithSubExpressions.Create(config, expr, hideOutermostValue).ComposeToSingleString();
 }
        static IEnumerable <Tuple <EqualityExpressionClass, bool> > DisagreeingEqualities(
            ExpressionToCodeConfiguration config,
            Expression left,
            Expression right,
            bool shouldBeEqual)
        {
            var leftC  = ToConstantExpr(config, left);
            var rightC = ToConstantExpr(config, right);

            Tuple <EqualityExpressionClass, bool> ReportIfError(EqualityExpressionClass eqClass, bool?itsVal) => shouldBeEqual == itsVal ? null : Tuple.Create(eqClass, !itsVal.HasValue);

            var ienumerableTypes =
                GetGenericInterfaceImplementation(leftC.Type, typeof(IEnumerable <>))
                .Intersect(GetGenericInterfaceImplementation(rightC.Type, typeof(IEnumerable <>)))
                .Select(seqType => seqType.GetTypeInfo().GetGenericArguments().Single());

            var seqEqualsMethod =
                ((Func <IEnumerable <int>, IEnumerable <int>, bool>)Enumerable.SequenceEqual).GetMethodInfo().GetGenericMethodDefinition();

            var iequatableEqualsMethods =
                (from genEquatable in GetGenericInterfaceImplementation(leftC.Type, typeof(IEquatable <>))
                 let otherType = genEquatable.GetTypeInfo().GetGenericArguments().Single()
                                 where otherType.GetTypeInfo().IsAssignableFrom(rightC.Type)
                                 let ifacemap = leftC.Type.GetTypeInfo().GetRuntimeInterfaceMap(genEquatable)
                                                select
                                                ifacemap.InterfaceMethods.Zip(ifacemap.InterfaceMethods, Tuple.Create)
                                                .Single(ifaceAndImpl => ifaceAndImpl.Item1.Name == "Equals")
                                                .Item2).Distinct();

            var errs = new[] {
                ReportIfError(EqualityExpressionClass.EqualsOp, EvalBoolExpr(config, Expression.Equal(leftC, rightC))),
                ReportIfError(EqualityExpressionClass.NotEqualsOp, EvalBoolExpr(config, Expression.Not(Expression.NotEqual(leftC, rightC)))),
                ReportIfError(
                    EqualityExpressionClass.ObjectEquals,
                    EvalBoolExpr(config, Expression.Call(leftC, objEqualInstanceMethod, Expression.Convert(rightC, typeof(object))))),
                ReportIfError(
                    EqualityExpressionClass.ObjectEqualsStatic,
                    EvalBoolExpr(
                        config, Expression.Call(
                            objEqualStaticMethod,
                            Expression.Convert(leftC, typeof(object)),
                            Expression.Convert(rightC, typeof(object))))),
                ReportIfError(EqualityExpressionClass.ObjectReferenceEquals, object.ReferenceEquals(leftC.Value, rightC.Value)),
                ReportIfError(
                    EqualityExpressionClass.StructuralEquals,
                    StructuralComparisons.StructuralEqualityComparer.Equals(leftC.Value, rightC.Value)),
            }.Concat(
                iequatableEqualsMethods.Select(
                    method =>
                    ReportIfError(
                        EqualityExpressionClass.EquatableEquals,
                        EvalBoolExpr(
                            config, Expression.Call(leftC, method, rightC))))
                )
            .Concat(
                ienumerableTypes.Select(
                    elemType =>
                    ReportIfError(
                        EqualityExpressionClass.SequenceEqual,
                        EvalBoolExpr(
                            config, Expression.Call(seqEqualsMethod.MakeGenericMethod(elemType), leftC, rightC))))
                );

            return(errs.Where(err => err != null).Distinct().ToArray());
        }
        public static IEnumerable <Tuple <EqualityExpressionClass, bool> > DisagreeingEqualities(ExpressionToCodeConfiguration config, Expression <Func <bool> > e)
        {
            var currEquals = ExtractEqualityType(e);

            if (currEquals.Item1 == EqualityExpressionClass.None)
            {
                return(null);
            }
            var currVal = EvalBoolLambda(config, e);

            if (!currVal.HasValue)
            {
                return(null);
            }
            return(DisagreeingEqualities(config, currEquals.Item2, currEquals.Item3, currVal.Value));
        }
Ejemplo n.º 34
0
 public IEnumerable <string> PrintInitializerContents(ExpressionToCodeConfiguration config, IEnumerable list)
 => PrintInitializerContents(config, (IEnumerable <KeyValuePair <TKey, TValue> >)list);
Ejemplo n.º 35
0
 public ExpressionToCodeImpl(ExpressionToCodeConfiguration config) => this.config = config;
        static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object val, int indent, int valueSize)
        {
            var retval = ObjectToCode.PlainObjectToCode(val);

            if (val is string)
            {
                return(ElidePossiblyMultilineString(config, retval, indent, valueSize).Trim());
            }
            else if (retval != null)
            {
                return(ElideAfter(retval, valueSize));
            }
            else if (val is Array arrayVal)
            {
                return("new[] " + FormatEnumerable(config, arrayVal, indent, valueSize - 6));
            }
            else if (val is IEnumerable enumerableVal)
            {
                var type = val.GetType();
                if (type.GetConstructor(Type.EmptyTypes) is ConstructorInfo ci && ci.IsPublic)
                {
                    foreach (var pi in type.GetProperties())
                    {
                        if (
                            pi.Name == "Item" &&
                            pi.CanWrite &&
                            pi.GetIndexParameters() is ParameterInfo[] indexPars &&
                            indexPars.Length == 1 &&
                            typeof(IEnumerable <>).MakeGenericType(typeof(KeyValuePair <,>).MakeGenericType(indexPars[0].ParameterType, pi.PropertyType)) is Type keyEnumerableType &&
                            keyEnumerableType.IsAssignableFrom(type)
                            )
                        {
                            var typeName = type.ToCSharpFriendlyTypeName();
                            return("new " + typeName + " " + PrintInitializerContents(config, enumerableVal, indexPars[0].ParameterType, pi.PropertyType, indent, valueSize - typeName.Length));
                        }
                    }
                }

                return(FormatEnumerable(config, enumerableVal, indent, valueSize));
            }
            else if (val is Expression exprVal)
            {
                return(ElideAfter(config.GetExpressionToCode().ToCode(exprVal), valueSize));
            }
            else if (val is IStructuralComparable tuple && val is IComparable && CSharpFriendlyTypeName.IsValueTupleType(val.GetType().GetTypeInfo()))
            {
                var collector = new NastyHackyTupleCollector();
                tuple.CompareTo(tuple, collector);
                var sb = new StringBuilder();
                sb.Append("(");
                for (var index = 0; index < collector.CollectedObjects.Count; index++)
                {
                    var item     = collector.CollectedObjects[index];
                    var asString = ComplexObjectToPseudoCode(config, item, indent + 4, valueSize);
                    if (index > 0)
                    {
                        sb.Append(", ");
                    }

                    sb.Append(asString);
                }

                sb.Append(")");
                return(ElidePossiblyMultilineString(config, sb.ToString(), indent, valueSize).Trim());
            }
Ejemplo n.º 37
0
 public static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object?val, int indent)
 => ComplexObjectToPseudoCode(config, val, indent, config.Value.MaximumValueLength ?? int.MaxValue);
Ejemplo n.º 38
0
        public static IEnumerable <Tuple <EqualityExpressionClass, bool> >?DisagreeingEqualities(ExpressionToCodeConfiguration config, Expression <Func <bool> > e)
        {
            var currEquals = ExtractEqualityType(e);

            if (currEquals == null)
            {
                return(null);
            }

            var currVal = EvalBoolLambda(config, e);

            if (!currVal.HasValue)
            {
                return(null);
            }

            return(DisagreeingEqualities(config, currEquals.Value.left, currEquals.Value.right, currVal.Value)
                   .Select(o => o.ToTuple())//purely to avoid breaking API changes
                   );
        }
 public string AnnotateExpressionTree(ExpressionToCodeConfiguration config, Expression expr, string msg, bool hideOutermostValue)
 => (msg == null ? "" : msg + "\n\n") + ExpressionWithSubExpressions.Create(config, expr, hideOutermostValue).ComposeToSingleString();