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; }
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)); }
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); }
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); }
private FoldResult ProcessUnaryExpression(UnaryOperatorExpression unaryOperatorExpression, FoldResult foldResult, object resultValue) { var textSpans = foldResult.TextSpans; textSpans.Add(unaryOperatorExpression.Operator.TextSpan); return(new FoldResult(resultValue, textSpans)); }
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); }