Пример #1
0
        private void NormalizeAndAdd(Ust ust, ref FoldResult result)
        {
            if (result?.Value is StringBuilder stringBuilder)
            {
                result = new FoldResult(stringBuilder.ToString(), result.TextSpans);
            }

            result?.TextSpans.Sort();
            foldedResults[ust.TextSpan] = result;
        }
Пример #2
0
        private FoldResult ProcessBinaryExpression(BinaryOperatorExpression binaryOperatorExpression,
                                                   FoldResult leftFold, FoldResult rightFold, object foldedBinaryValue)
        {
            var textSpans = leftFold.TextSpans;

            if (!(foldedBinaryValue is string || foldedBinaryValue is StringBuilder))
            {
                textSpans.Add(binaryOperatorExpression.Operator.TextSpan); // FIXME: workaround for correct PatternStringRegexLiteral processing
            }
            textSpans.AddRange(rightFold.TextSpans);

            return(new FoldResult(foldedBinaryValue, leftFold.TextSpans));
        }
Пример #3
0
        private FoldResult TryFoldUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
        {
            FoldResult foldResult = TryGetOrFold(unaryOperatorExpression.Expression);

            if (foldResult == null)
            {
                NormalizeAndAdd(unaryOperatorExpression.Expression, ref foldResult);
                return(null);
            }

            if (unaryOperatorExpression.Operator.UnaryOperator == UnaryOperator.Minus)
            {
                object negativeValue = null;
                switch (foldResult.Value)
                {
                case double doubleVal:
                    negativeValue = -doubleVal;
                    break;

                case int intVal:
                    negativeValue = -intVal;
                    break;

                case long longVal:
                    negativeValue = -longVal;
                    break;

                case BigInteger bigIntVal:
                    negativeValue = -bigIntVal;
                    break;
                }

                if (negativeValue != null)
                {
                    return(ProcessUnaryExpression(unaryOperatorExpression, foldResult, negativeValue));
                }
            }

            return(null);
        }
Пример #4
0
        public bool TryGetOrFold(Ust ust, out FoldResult result)
        {
            if (ust == null || !foldingTypes.Contains(ust.GetType()))
            {
                result = null;
                return(false);
            }

            lock (ust)
            {
                if (foldedResults.TryGetValue(ust.TextSpan, out result))
                {
                    return(result != null);
                }

                result = TryGetOrFold(ust);

                NormalizeAndAdd(ust, ref result);
            }

            return(result != null);
        }
Пример #5
0
        private FoldResult ProcessUnaryExpression(UnaryOperatorExpression unaryOperatorExpression, FoldResult foldResult,
                                                  object resultValue)
        {
            var textSpans = foldResult.TextSpans;

            textSpans.Add(unaryOperatorExpression.Operator.TextSpan);

            return(new FoldResult(resultValue, textSpans));
        }
Пример #6
0
        private FoldResult TryFoldBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
        {
            FoldResult leftFold = TryGetOrFold(binaryOperatorExpression.Left);

            if (leftFold == null)
            {
                NormalizeAndAdd(binaryOperatorExpression.Left, ref leftFold);
                return(null);
            }

            FoldResult rightFold = TryGetOrFold(binaryOperatorExpression.Right);

            if (rightFold == null)
            {
                NormalizeAndAdd(binaryOperatorExpression.Right, ref rightFold);
                return(null);
            }

            object leftValue         = leftFold.Value;
            object rightValue        = rightFold.Value;
            BinaryOperatorLiteral op = binaryOperatorExpression.Operator;

            if (leftValue is string || leftValue is StringBuilder)
            {
                if (op.BinaryOperator == BinaryOperator.Plus || op.BinaryOperator == BinaryOperator.Concat)
                {
                    // Use StringBuilder instead of immutable strings and concatenation
                    string rightString = rightValue.ToString();

                    StringBuilder leftStringBuilder;
                    if (leftValue is string leftString)
                    {
                        leftStringBuilder = new StringBuilder((leftString.Length + rightString.Length) * 2);
                        leftStringBuilder.Append(leftString);
                    }
                    else
                    {
                        leftStringBuilder = (StringBuilder)leftValue;
                    }
                    leftStringBuilder.Append(rightString);

                    FoldResult result = ProcessBinaryExpression(binaryOperatorExpression, leftFold, rightFold, leftStringBuilder);

                    if (Logger.IsLogDebugs)
                    {
                        Logger.LogDebug(
                            $"Strings {binaryOperatorExpression} concatenated to \"{leftStringBuilder}\" at {binaryOperatorExpression.TextSpan}");
                    }

                    return(result);
                }
            }
            else
            {
                if (TryFoldIntBinaryOperatorExpression(leftValue, rightValue, op, out BigInteger bigInt))
                {
                    FoldResult result = ProcessBinaryExpression(binaryOperatorExpression, leftFold, rightFold, bigInt);

                    if (Logger.IsLogDebugs)
                    {
                        Logger.LogDebug($"Arithmetic expression {binaryOperatorExpression} folded to {bigInt} at {binaryOperatorExpression.TextSpan}");
                    }

                    return(result);
                }
            }

            return(null);
        }