From 755641c9f3837013a60f0d40e5133ad09f885601 Mon Sep 17 00:00:00 2001
From: anderson-joyle <joyle@outlook.com>
Date: Mon, 11 Nov 2024 10:52:07 -0600
Subject: [PATCH] API to get static text from parser

---
 .../Parser/ParseResult.cs                     | 29 +++++++++++++++++++
 .../ParseTests.cs                             | 16 ++++++++++
 2 files changed, 45 insertions(+)

diff --git a/src/libraries/Microsoft.PowerFx.Core/Parser/ParseResult.cs b/src/libraries/Microsoft.PowerFx.Core/Parser/ParseResult.cs
index 642d499820..a7de4acc57 100644
--- a/src/libraries/Microsoft.PowerFx.Core/Parser/ParseResult.cs
+++ b/src/libraries/Microsoft.PowerFx.Core/Parser/ParseResult.cs
@@ -118,5 +118,34 @@ public string GetAnonymizedFormula()
         {
             return StructuralPrint.Print(Root);
         }
+
+        /// <summary>
+        /// Checks if the expression does not depend on extra evaluations.
+        /// Examples: 
+        /// "Lorem ipsum" // is a static expression since there is no extra evaluation needed.
+        /// "Today is " & Today() // is not a static expression since the function call 'Today()' needs to be evaluated.
+        /// $"Today is {""some text""}" // is not a static expression since the interpolation needs to be evaluated.
+        /// </summary>
+        /// <returns>True if no extra evaluation is needed. False otherwise.</returns>
+        public bool TryGetStaticTextExpression(out string staticExpression)
+        { 
+            if (Options.TextFirst &&
+                Root is StrInterpNode strInterpNode &&
+                strInterpNode.ChildNodes.Count == 1 &&
+                strInterpNode.ChildNodes.First() is StrLitNode strLitNode)
+            {
+                staticExpression = strLitNode.Value;
+                return true;
+            }
+
+            if (Root is StrLitNode strLitNode1)
+            {
+                staticExpression = strLitNode1.Value;
+                return true;
+            }
+
+            staticExpression = null;
+            return false;
+        }
     }
 }
diff --git a/src/tests/Microsoft.PowerFx.Core.Tests.Shared/ParseTests.cs b/src/tests/Microsoft.PowerFx.Core.Tests.Shared/ParseTests.cs
index 1695c2f576..de170e309b 100644
--- a/src/tests/Microsoft.PowerFx.Core.Tests.Shared/ParseTests.cs
+++ b/src/tests/Microsoft.PowerFx.Core.Tests.Shared/ParseTests.cs
@@ -1026,5 +1026,21 @@ public void TestTypeLiteralInNamedFormula(string script, int namedFormulaCount)
             Assert.Equal(namedFormulaCount, parseResult.NamedFormulas.Count());
             Assert.Contains(parseResult.Errors, e => e.MessageKey.Contains("ErrUserDefinedTypeIncorrectSyntax"));
         }
+
+        [Theory]
+        [InlineData("\"static text\"", "static text", false, true)]
+        [InlineData("$\"not static {\"text\"}\"", null, false, false)]
+        [InlineData("\"not\" & \"static\" & \"text\"", null, false, false)]
+
+        // TextFirst
+        [InlineData("static text", "static text", true, true)]
+        [InlineData("not static ${\"text\"}", null, true, false)]
+        public void TryGetStaticTextExpressionTest(string expression, string result, bool textFirst, bool isStaticText)
+        {
+            var opt = new ParserOptions() { TextFirst = textFirst };
+            var parseResult = Engine.Parse(expression, options: opt);
+            Assert.Equal(isStaticText, parseResult.TryGetStaticTextExpression(out var outResult));
+            Assert.Equal(result, outResult);
+        }
     }
 }