Store functions in optimized TexlFunctionSet<TexlFunction> object
instead of IEnumerable<TextFunction>

Benchmark results
- -61% for Check N=1
- -77% for Check N=5
- -79% for Check N=10
- -42% for Eval N=1
- -65% for Eval N=5
- -67% for Eval N=10

Negligible improvement for Parse , Tokenize or PVA* benchmarks
This commit is contained in:
Luc Genetier 2023-02-23 16:14:37 +01:00 коммит произвёл GitHub
Родитель 83e3f81772
Коммит 341a621f3b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
41 изменённых файлов: 1221 добавлений и 507 удалений

Просмотреть файл

@ -226,7 +226,7 @@ $list = (Get-Item -Filter *.csv -Path '.\BenchmarkDotNet.Artifacts\results\*' |
foreach ($file in [System.Linq.Enumerable]::OrderBy($list, [Func[object, string]] { param($s) if ($s -match 'Reference-report\.csv') { "" } else { $s } }))
{
$t = [System.IO.Path]::GetFileNameWithoutExtension($file).Split(@('.'))[-1]
$testCategory = $t.Substring(0, $t.Length - 7)
if ($t.Length -gt 7) { $testCategory = $t.Substring(0, $t.Length - 7) } else { $testCategory = $t }
Write-Host "------ [TEST] $testCategory ------"

Просмотреть файл

@ -57,6 +57,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerFx.Json", "l
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerFx.Json.Tests", "tests\Microsoft.PowerFx.Json.Tests\Microsoft.PowerFx.Json.Tests.csproj", "{8986E836-2F55-4D71-B23E-50F4A8427A5B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmark", "Benchmark", "{89514D49-4D5D-4423-A6EC-F0FF1D23EF43}"
ProjectSection(SolutionItems) = preProject
ReadBenchmarkData.ps1 = ReadBenchmarkData.ps1
..\.scripts\WriteBenchmark.ps1 = ..\.scripts\WriteBenchmark.ps1
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -128,6 +134,7 @@ Global
{142854D7-409C-4C87-A5B8-39B51477F5B2} = {5EEC2873-35B5-4364-A2A0-97AAD7BF960D}
{D4CC6660-8C30-41E5-A28A-C018DDDF8D96} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
{8986E836-2F55-4D71-B23E-50F4A8427A5B} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
{89514D49-4D5D-4423-A6EC-F0FF1D23EF43} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {30372F91-B206-4351-A621-F0E2773C337B}

Просмотреть файл

@ -21,7 +21,7 @@ function ConvertToMs([string]$str)
## Convert to milliseconds
if ($parts[1] -eq "s") { $val *= 1000 }
elseif ($parts[1] -eq "ms") { } ## Do nothing
elseif ($parts[1] -eq "µs") { $val /= 1000 }
elseif ($parts[1] -eq "μs") { $val /= 1000 }
elseif ($parts[1] -eq "ns") { $val /= 1000000 }
else { throw ("Unknown unit: " + $parts[1]) }
}
@ -172,7 +172,7 @@ $list = (Get-Item -Filter *.csv -Path '.\BenchmarkDotNet.Artifacts\results\*' |
foreach ($file in [System.Linq.Enumerable]::OrderBy($list, [Func[object, string]] { param($s) if ($s -match 'Reference-report\.csv') { "" } else { $s } }))
{
$t = [System.IO.Path]::GetFileNameWithoutExtension($file).Split(@('.'))[-1]
$testCategory = $t.Substring(0, $t.Length - 7)
if ($t.Length -gt 7) { $testCategory = $t.Substring(0, $t.Length - 7) } else { $testCategory = $t }
Write-Host "------ [TEST] $testCategory ------"

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.PowerFx.Core.Binding
DPath CurrentEntityPath { get; }
IEnumerable<TexlFunction> Functions { get; }
TexlFunctionSet Functions { get; }
// This advertises whether the INameResolver instance will suggest unqualified enums ("Hours")
// or only qualified enums ("TimeUnit.Hours").

Просмотреть файл

@ -7,8 +7,6 @@ using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.PowerFx.Core.App.ErrorContainers;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Entities;
@ -27,7 +25,6 @@ using Microsoft.PowerFx.Core.Logging.Trackers;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Syntax;
using Microsoft.PowerFx.Types;
using static Microsoft.PowerFx.Core.IR.IRTranslator;
using CallNode = Microsoft.PowerFx.Syntax.CallNode;
using IRCallNode = Microsoft.PowerFx.Core.IR.Nodes.CallNode;
@ -362,7 +359,7 @@ namespace Microsoft.PowerFx.Core.Functions
// This can be used to generate a list of enums required for a function library.
public virtual IEnumerable<string> GetRequiredEnumNames()
{
return new List<string>();
return Enumerable.Empty<string>();
}
// Return all signatures with at most 'arity' parameters.

Просмотреть файл

@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.PowerFx.Core.Functions
{
internal class TexlFunctionComparer : IEqualityComparer<TexlFunction>
{
public bool Equals(TexlFunction x, TexlFunction y)
{
return object.Equals(x, y);
}
public int GetHashCode(TexlFunction obj)
{
return obj.GetHashCode();
}
}
}

Просмотреть файл

@ -0,0 +1,361 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerFx.Core.Utils;
namespace Microsoft.PowerFx.Core.Functions
{
internal class TexlFunctionSet
{
// Dictionary key: function.Name
private Dictionary<string, List<TexlFunction>> _functions;
// Dictionary key: function.LocaleInvariantName
private Dictionary<string, List<TexlFunction>> _functionsInvariant;
// Dictionary key: function.Namespace
private Dictionary<DPath, List<TexlFunction>> _namespaces;
// List of all function.GetRequiredEnumNames()
private List<string> _enums;
// Count of functions
internal int _count;
internal Dictionary<string, List<TexlFunction>>.KeyCollection FunctionNames => _functions.Keys;
internal Dictionary<string, List<TexlFunction>>.KeyCollection InvariantFunctionNames => _functionsInvariant.Keys;
internal Dictionary<DPath, List<TexlFunction>>.KeyCollection Namespaces => _namespaces.Keys;
internal IEnumerable<TexlFunction> WithName(string name) => WithNameInternal(name);
private List<TexlFunction> WithNameInternal(string name) => _functions.TryGetValue(name, out List<TexlFunction> result) ? result : new List<TexlFunction>();
internal IEnumerable<TexlFunction> WithName(string name, DPath ns) => _functions.TryGetValue(name, out List<TexlFunction> result) ? result.Where(f => f.Namespace == ns) : new List<TexlFunction>();
internal IEnumerable<TexlFunction> WithInvariantName(string name) => WithInvariantNameInternal(name);
private List<TexlFunction> WithInvariantNameInternal(string name) => _functionsInvariant.TryGetValue(name, out List<TexlFunction> result) ? result : new List<TexlFunction>();
internal IEnumerable<TexlFunction> WithInvariantName(string name, DPath ns) => _functionsInvariant.TryGetValue(name, out List<TexlFunction> result) ? result.Where(f => f.Namespace == ns) : new List<TexlFunction>();
internal IEnumerable<TexlFunction> WithNamespace(DPath ns) => WithNamespaceInternal(ns);
private List<TexlFunction> WithNamespaceInternal(DPath ns) => _namespaces.TryGetValue(ns, out List<TexlFunction> result) ? result : new List<TexlFunction>();
internal IEnumerable<string> Enums => _enums;
internal TexlFunctionSet()
{
_functions = new Dictionary<string, List<TexlFunction>>(StringComparer.Ordinal);
_functionsInvariant = new Dictionary<string, List<TexlFunction>>(StringComparer.OrdinalIgnoreCase);
_namespaces = new Dictionary<DPath, List<TexlFunction>>();
_enums = new List<string>();
_count = 0;
}
internal TexlFunctionSet(TexlFunction function)
: this()
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
_functions.Add(function.Name, new List<TexlFunction>() { function });
_functionsInvariant.Add(function.LocaleInvariantName, new List<TexlFunction>() { function });
_namespaces.Add(function.Namespace, new List<TexlFunction> { function });
_enums = new List<string>(function.GetRequiredEnumNames());
_count = 1;
}
internal TexlFunctionSet(IEnumerable<TexlFunction> functions)
: this()
{
if (functions == null)
{
throw new ArgumentNullException(nameof(functions));
}
foreach (var func in functions)
{
Add(func);
}
}
internal TexlFunctionSet(IEnumerable<TexlFunctionSet> functionSets)
: this()
{
if (functionSets == null)
{
throw new ArgumentNullException(nameof(functionSets));
}
foreach (var functionSet in functionSets)
{
if (functionSet._count > 0)
{
Add(functionSet);
}
}
}
// Slow API, only use for backward compatibility
[Obsolete("Slow API. Prefer using With* functions for identifying functions you need.")]
internal IEnumerable<TexlFunction> Functions
{
get
{
foreach (var kvp in _functions.ToList())
{
foreach (var func in kvp.Value)
{
yield return func;
}
}
}
}
internal TexlFunction Add(TexlFunction function)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
List<TexlFunction> fList = WithNameInternal(function.Name);
List<TexlFunction> fInvariantList = WithInvariantNameInternal(function.LocaleInvariantName);
List<TexlFunction> fNsList = WithNamespaceInternal(function.Namespace);
bool fListAny = fList.Any();
bool fInvariantListAny = fInvariantList.Any();
bool fNsListAny = fNsList.Any();
if (fListAny && fList.Contains(function))
{
throw new ArgumentException($"Function {function.Name} is already part of core or extra functions");
}
if (fInvariantListAny && fInvariantList.Contains(function))
{
throw new ArgumentException($"Function {function.Name} is already part of core or extra functions (invariant)");
}
if (fNsListAny && fNsList.Contains(function))
{
throw new ArgumentException($"Function {function.Name} is already part of core or extra functions (namespace)");
}
if (fListAny)
{
fList.Add(function);
}
else
{
_functions.Add(function.Name, new List<TexlFunction>() { function });
}
if (fInvariantListAny)
{
fInvariantList.Add(function);
}
else
{
_functionsInvariant.Add(function.LocaleInvariantName, new List<TexlFunction>() { function });
}
if (fNsListAny)
{
fNsList.Add(function);
}
else
{
_namespaces.Add(function.Namespace, new List<TexlFunction>() { function });
}
_enums.AddRange(function.GetRequiredEnumNames());
_count++;
return function;
}
internal TexlFunctionSet Add(TexlFunctionSet functionSet)
{
if (functionSet == null)
{
throw new ArgumentNullException(nameof(functionSet));
}
// Notice that this code path is a critical performance gain versus the various loops in the 'else' part
if (_count == 0)
{
_functions = functionSet._functions.ToDictionary(kvp => kvp.Key, kvp => new List<TexlFunction>(kvp.Value));
_functionsInvariant = functionSet._functionsInvariant.ToDictionary(kvp => kvp.Key, kvp => new List<TexlFunction>(kvp.Value));
_namespaces = functionSet._namespaces.ToDictionary(kvp => kvp.Key, kvp => new List<TexlFunction>(kvp.Value));
_enums = new List<string>(functionSet._enums);
_count = functionSet._count;
}
else
{
foreach (var key in functionSet.FunctionNames)
{
var newFuncs = functionSet.WithNameInternal(key);
var fList = WithNameInternal(key);
if (fList.Any())
{
fList.AddRange(newFuncs);
}
else
{
_functions.Add(key, newFuncs);
}
_count += newFuncs.Count();
}
foreach (var key in functionSet.InvariantFunctionNames)
{
var newFuncs = functionSet.WithInvariantNameInternal(key);
var fInvariantList = WithInvariantNameInternal(key);
if (fInvariantList.Any())
{
fInvariantList.AddRange(newFuncs);
}
else
{
_functionsInvariant.Add(key, newFuncs);
}
}
foreach (var key in functionSet.Namespaces)
{
var newFuncs = functionSet.WithNamespaceInternal(key);
var fnsList = WithNamespaceInternal(key);
if (fnsList.Any())
{
fnsList.AddRange(newFuncs);
}
else
{
_namespaces.Add(key, newFuncs);
}
}
_enums.AddRange(functionSet._enums);
}
return this;
}
internal void Add(IEnumerable<TexlFunction> functions)
{
if (functions == null)
{
throw new ArgumentNullException(nameof(functions));
}
foreach (var t in functions)
{
Add(t);
}
}
internal int Count()
{
return _count;
}
internal bool Any()
{
return _count != 0;
}
internal bool AnyWithName(string name) => _functions.ContainsKey(name);
internal void RemoveAll(string name)
{
if (_functions.TryGetValue(name, out List<TexlFunction> removed))
{
_count -= removed.Count();
_functions.Remove(name);
}
if (_functionsInvariant.TryGetValue(name, out _))
{
_functionsInvariant.Remove(name);
}
if (removed != null && removed.Any())
{
foreach (TexlFunction f in removed)
{
List<TexlFunction> fnsList = WithNamespaceInternal(f.Namespace);
if (fnsList.Count == 1)
{
_namespaces.Remove(f.Namespace);
}
else
{
fnsList.Remove(f);
}
f.GetRequiredEnumNames().ToList().ForEach(removedEnum => _enums.Remove(removedEnum));
}
}
// If functions with the given name aren't found, this is ok.
}
internal void RemoveAll(TexlFunction function)
{
if (_functions.TryGetValue(function.Name, out List<TexlFunction> funcs))
{
_count--;
funcs.Remove(function);
if (!funcs.Any())
{
_functions.Remove(function.Name);
}
}
if (_functionsInvariant.TryGetValue(function.Name, out List<TexlFunction> funcs2))
{
funcs2.Remove(function);
if (!funcs2.Any())
{
_functionsInvariant.Remove(function.Name);
}
}
if (_namespaces.TryGetValue(function.Namespace, out List<TexlFunction> funcs3))
{
funcs3.Remove(function);
if (!funcs3.Any())
{
_namespaces.Remove(function.Namespace);
}
}
IEnumerable<string> enums = function.GetRequiredEnumNames();
if (enums.Any())
{
foreach (string enumName in enums)
{
_enums.Remove(enumName);
}
}
}
}
}

Просмотреть файл

@ -16,4 +16,4 @@ namespace Microsoft.PowerFx.Core.Functions
return !(value & (BigInteger.One << bitIndex)).IsZero;
}
}
}
}

Просмотреть файл

@ -4,12 +4,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerFx.Core.App;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Entities;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;
@ -20,7 +18,7 @@ namespace Microsoft.PowerFx
/// Composition of multiple <see cref="ReadOnlySymbolTable"/> into a single table.
/// </summary>
internal class ComposedReadOnlySymbolTable : ReadOnlySymbolTable, INameResolver, IGlobalSymbolNameResolver, IEnumStore
{
{
private readonly IEnumerable<ReadOnlySymbolTable> _symbolTables;
// In priority order.
@ -32,7 +30,7 @@ namespace Microsoft.PowerFx
}
internal IEnumerable<ReadOnlySymbolTable> SubTables => _symbolTables;
internal override VersionHash VersionHash
{
get
@ -60,18 +58,27 @@ namespace Microsoft.PowerFx
return slot.Owner.GetTypeFromSlot(slot);
}
private TexlFunctionSet _nameResolverFunctions = null;
private VersionHash _cachedVersionHash = VersionHash.New();
// Expose the list to aide in intellisense suggestions.
IEnumerable<TexlFunction> INameResolver.Functions
TexlFunctionSet INameResolver.Functions
{
get
{
foreach (INameResolver table in _symbolTables)
var current = this.VersionHash;
if (current != _cachedVersionHash)
{
foreach (var function in table.Functions)
{
yield return function;
}
_nameResolverFunctions = null;       
}
if (_nameResolverFunctions == null)
{
_nameResolverFunctions = new TexlFunctionSet(_symbolTables.Select(t => t.Functions).ToList());
_cachedVersionHash = current;
}
return _nameResolverFunctions;
}
}
@ -134,16 +141,15 @@ namespace Microsoft.PowerFx
Contracts.Check(theNamespace.IsValid, "The namespace is invalid.");
Contracts.CheckNonEmpty(name, "name");
// See TexlFunctionsLibrary.Lookup
var functionLibrary = Functions.Where(func => func.Namespace == theNamespace && name == (localeInvariant ? func.LocaleInvariantName : func.Name)); // Base filter
return functionLibrary;
return localeInvariant
? Functions.WithInvariantName(name, theNamespace)
: Functions.WithName(name, theNamespace);
}
public IEnumerable<TexlFunction> LookupFunctionsInNamespace(DPath nameSpace)
{
Contracts.Check(nameSpace.IsValid, "The namespace is invalid.");
return Functions.Where(function => function.Namespace.Equals(nameSpace));
return Functions.WithNamespace(nameSpace);
}
public virtual bool LookupGlobalEntity(DName name, out NameLookupInfo lookupInfo)

Просмотреть файл

@ -2,15 +2,11 @@
// Licensed under the MIT license.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Entities;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;
@ -34,9 +30,7 @@ namespace Microsoft.PowerFx
// Full universe of possible symbols
// All other symbols are missing.
public DeferredSymbolTable(
DisplayNameProvider map,
Func<string, string, FormulaType> fetchTypeInfo)
public DeferredSymbolTable(DisplayNameProvider map, Func<string, string, FormulaType> fetchTypeInfo)
{
_displayNameLookup = map ?? throw new ArgumentNullException(nameof(map));
_fetchTypeInfo = fetchTypeInfo ?? throw new ArgumentNullException(nameof(fetchTypeInfo));
@ -49,9 +43,7 @@ namespace Microsoft.PowerFx
// Must be thread safe!!!
// We can have multiple threads reading; which means they may be populating the cache.
private readonly object _lock = new object();
private readonly Dictionary<string, NameLookupInfo> _variables = new Dictionary<string, NameLookupInfo>();
private readonly object _lock = new object();
private readonly SlotMap<NameLookupInfo?> _slots = new SlotMap<NameLookupInfo?>();

Просмотреть файл

@ -37,9 +37,10 @@ namespace Microsoft.PowerFx
/// Added on 6th December 2022.
/// </summary>
SupportColumnNamesAsIdentifiers = 0x8,
/// <summary>
/// All features enabled
/// [USE WITH CAUTION] In using this value, you expose your code to future features.
/// </summary>
All = ~0
}

Просмотреть файл

@ -69,9 +69,9 @@ namespace Microsoft.PowerFx
/// </summary>
[Obsolete("Migrate to SymbolTables")]
public IEnumerable<FunctionInfo> FunctionInfos =>
new Engine(this).SupportedFunctions.Functions
.Concat(SymbolTable.Functions)
.Select(f => new FunctionInfo(f));
new Engine(this).SupportedFunctions.Functions.Functions
.Concat(SymbolTable.Functions.Functions)
.Select(f => new FunctionInfo(f));
/// <summary>
/// Initializes a new instance of the <see cref="PowerFxConfig"/> class.
@ -79,7 +79,7 @@ namespace Microsoft.PowerFx
/// <param name="cultureInfo">Culture to use.</param>
/// <param name="features">Features to use.</param>
public PowerFxConfig(CultureInfo cultureInfo, Features features)
: this(cultureInfo, new EnumStoreBuilder().WithRequiredEnums(BuiltinFunctionsCore.BuiltinFunctionsLibrary), features)
: this(cultureInfo, new EnumStoreBuilder().WithRequiredEnums(BuiltinFunctionsCore._library), features)
{
}
@ -102,22 +102,19 @@ namespace Microsoft.PowerFx
internal static PowerFxConfig BuildWithEnumStore(CultureInfo cultureInfo, EnumStoreBuilder enumStoreBuilder, Features features)
{
return BuildWithEnumStore(cultureInfo, enumStoreBuilder, Core.Texl.BuiltinFunctionsCore.BuiltinFunctionsLibrary, features: features);
return BuildWithEnumStore(cultureInfo, enumStoreBuilder, BuiltinFunctionsCore._library, features: features);
}
internal static PowerFxConfig BuildWithEnumStore(CultureInfo cultureInfo, EnumStoreBuilder enumStoreBuilder, IEnumerable<TexlFunction> coreFunctions)
internal static PowerFxConfig BuildWithEnumStore(CultureInfo cultureInfo, EnumStoreBuilder enumStoreBuilder, TexlFunctionSet coreFunctions)
{
return BuildWithEnumStore(cultureInfo, enumStoreBuilder, coreFunctions, Features.None);
}
internal static PowerFxConfig BuildWithEnumStore(CultureInfo cultureInfo, EnumStoreBuilder enumStoreBuilder, IEnumerable<TexlFunction> coreFunctions, Features features)
internal static PowerFxConfig BuildWithEnumStore(CultureInfo cultureInfo, EnumStoreBuilder enumStoreBuilder, TexlFunctionSet coreFunctions, Features features)
{
var config = new PowerFxConfig(cultureInfo, enumStoreBuilder, features);
foreach (var func in coreFunctions)
{
config.AddFunction(func);
}
config.AddFunctions(coreFunctions);
return config;
}
@ -141,45 +138,41 @@ namespace Microsoft.PowerFx
internal void AddFunction(TexlFunction function)
{
var comparer = new TexlFunctionComparer();
if (!SymbolTable.Functions.Contains(function, comparer))
if (function.HasLambdas || function.HasColumnIdentifiers)
{
if (function.HasLambdas || function.HasColumnIdentifiers)
// We limit to 20 arguments as MaxArity could be set to int.MaxValue
// and checking up to 20 arguments is enough for this validation
for (var i = 0; i < Math.Min(function.MaxArity, 20); i++)
{
if (function.HasLambdas && function.HasColumnIdentifiers && function.IsLambdaParam(i) && function.IsIdentifierParam(i))
{
(var message, var _) = ErrorUtils.GetLocalizedErrorContent(TexlStrings.ErrInvalidFunction, null, out var errorResource);
throw new ArgumentException(message);
}
}
var overloads = SymbolTable.Functions.WithName(function.Name).Where(tf => tf.HasLambdas || tf.HasColumnIdentifiers);
if (overloads.Any())
{
// We limit to 20 arguments as MaxArity could be set to int.MaxValue
// and checking up to 20 arguments is enough for this validation
for (var i = 0; i < Math.Min(function.MaxArity, 20); i++)
{
if (function.HasLambdas && function.HasColumnIdentifiers && function.IsLambdaParam(i) && function.IsIdentifierParam(i))
if ((function.IsLambdaParam(i) && overloads.Any(ov => ov.HasColumnIdentifiers && ov.IsIdentifierParam(i))) ||
(function.IsIdentifierParam(i) && overloads.Any(ov => ov.HasLambdas && ov.IsLambdaParam(i))))
{
(var message, var _) = ErrorUtils.GetLocalizedErrorContent(TexlStrings.ErrInvalidFunction, null, out var errorResource);
throw new ArgumentException(message);
}
}
var overloads = SymbolTable.Functions.Where(tf => tf.Name == function.Name && (tf.HasLambdas || tf.HasColumnIdentifiers));
if (overloads.Any())
{
for (var i = 0; i < Math.Min(function.MaxArity, 20); i++)
{
if ((function.IsLambdaParam(i) && overloads.Any(ov => ov.HasColumnIdentifiers && ov.IsIdentifierParam(i))) ||
(function.IsIdentifierParam(i) && overloads.Any(ov => ov.HasLambdas && ov.IsLambdaParam(i))))
{
(var message, var _) = ErrorUtils.GetLocalizedErrorContent(TexlStrings.ErrInvalidFunction, null, out var errorResource);
throw new ArgumentException(message);
}
}
}
}
}
SymbolTable.AddFunction(function);
}
else
{
throw new ArgumentException($"Function {function.Name} is already part of core or extra functions");
}
SymbolTable.AddFunction(function);
}
internal void AddFunctions(TexlFunctionSet functionSet)
{
SymbolTable.AddFunctions(functionSet);
}
public void AddOptionSet(OptionSet optionSet, DName optionalDisplayName = default)

Просмотреть файл

@ -11,6 +11,7 @@ using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Entities;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
@ -43,7 +44,7 @@ namespace Microsoft.PowerFx
{
_version.Inc();
}
private protected string _debugName = "SymbolTable";
// Helper in debugging. Useful when we have multiple symbol tables chained.
@ -90,7 +91,7 @@ namespace Microsoft.PowerFx
{
if (x.Value.Data is ISymbolSlot slot2)
{
if (slot2.SlotIndex == slot.SlotIndex)
if (slot2.SlotIndex == slot.SlotIndex)
{
return FormulaType.Build(x.Value.Type);
}
@ -176,7 +177,7 @@ namespace Microsoft.PowerFx
// Helper to create a ReadOnly symbol table around a set of core functions.
// Important that this is readonly so that it can be safely shared across engines.
internal static ReadOnlySymbolTable NewDefault(IEnumerable<TexlFunction> coreFunctions)
internal static ReadOnlySymbolTable NewDefault(TexlFunctionSet coreFunctions)
{
var s = new SymbolTable
{
@ -184,12 +185,21 @@ namespace Microsoft.PowerFx
DebugName = $"BuiltinFunctions ({coreFunctions.Count()})"
};
foreach (var func in coreFunctions)
{
s.AddFunction(func); // will also add enum.
}
s.AddFunctions(coreFunctions);
return s;
}
internal static ReadOnlySymbolTable NewDefault(IEnumerable<TexlFunction> functions)
{
TexlFunctionSet tfs = new TexlFunctionSet();
foreach (TexlFunction function in functions)
{
tfs.Add(function);
}
return NewDefault(tfs);
}
/// <summary>
@ -204,15 +214,14 @@ namespace Microsoft.PowerFx
DebugName = DebugName + " (Functions only)",
};
foreach (var func in _functions)
{
s.AddFunction(func);
}
s.AddFunctions(_functions);
return s;
}
private protected readonly List<TexlFunction> _functions = new List<TexlFunction>();
internal readonly Dictionary<string, NameLookupInfo> _variables = new Dictionary<string, NameLookupInfo>();
private protected readonly TexlFunctionSet _functions = new TexlFunctionSet();
// Which enums are available.
// These do not compose - only bottom one wins.
@ -242,25 +251,25 @@ namespace Microsoft.PowerFx
IEnumerable<EnumSymbol> IEnumStore.EnumSymbols => GetEnumSymbolSnapshot;
internal IEnumerable<TexlFunction> Functions => ((INameResolver)this).Functions;
internal TexlFunctionSet Functions => ((INameResolver)this).Functions;
IEnumerable<TexlFunction> INameResolver.Functions => _functions;
IEnumerable<KeyValuePair<string, NameLookupInfo>> IGlobalSymbolNameResolver.GlobalSymbols => Enumerable.Empty<KeyValuePair<string, NameLookupInfo>>();
TexlFunctionSet INameResolver.Functions => _functions;
IEnumerable<KeyValuePair<string, NameLookupInfo>> IGlobalSymbolNameResolver.GlobalSymbols => _variables;
/// <summary>
/// Get symbol names in this current scope.
/// </summary>
public IEnumerable<NamedFormulaType> SymbolNames
{
get
get
{
IGlobalSymbolNameResolver globals = this;
// GlobalSymbols are virtual, so we get derived behavior via that.
foreach (var kv in globals.GlobalSymbols)
{
var type = FormulaType.Build(kv.Value.Type);
var type = FormulaType.Build(kv.Value.Type);
var displayName = kv.Value.DisplayName != default ? kv.Value.DisplayName.Value : null;
yield return new NamedFormulaType(kv.Key, type, displayName);
}
@ -312,17 +321,16 @@ namespace Microsoft.PowerFx
Contracts.Check(theNamespace.IsValid, "The namespace is invalid.");
Contracts.CheckNonEmpty(name, "name");
// See TexlFunctionsLibrary.Lookup
// return _functionLibrary.Lookup(theNamespace, name, localeInvariant, null);
var functionLibrary = _functions.Where(func => func.Namespace == theNamespace && name == (localeInvariant ? func.LocaleInvariantName : func.Name)); // Base filter
return functionLibrary;
return localeInvariant
? Functions.WithInvariantName(name, theNamespace)
: Functions.WithName(name, theNamespace);
}
IEnumerable<TexlFunction> INameResolver.LookupFunctionsInNamespace(DPath nameSpace)
{
Contracts.Check(nameSpace.IsValid, "The namespace is invalid.");
return _functions.Where(function => function.Namespace.Equals(nameSpace));
return _functions.WithNamespace(nameSpace);
}
#region INameResolver - only implemented for unit testing for scenarios that use the full name resolver

Просмотреть файл

@ -1,9 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PowerFx.Core.Utils;
namespace Microsoft.PowerFx

Просмотреть файл

@ -2,7 +2,7 @@
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.Binding;
@ -25,9 +25,6 @@ namespace Microsoft.PowerFx
{
private readonly SlotMap<NameLookupInfo?> _slots = new SlotMap<NameLookupInfo?>();
// $$$ NEeded by config... make private?
internal readonly Dictionary<string, NameLookupInfo> _variables = new Dictionary<string, NameLookupInfo>();
private DisplayNameProvider _environmentSymbolDisplayNameProvider = new SingleSourceDisplayNameProvider();
IEnumerable<KeyValuePair<string, NameLookupInfo>> IGlobalSymbolNameResolver.GlobalSymbols => _variables;
@ -207,14 +204,29 @@ namespace Microsoft.PowerFx
{
Inc();
_functions.RemoveAll(func => func.Name == name);
_functions.RemoveAll(name);
}
internal void RemoveFunction(TexlFunction function)
{
Inc();
_functions.RemoveAll(func => func == function);
_functions.RemoveAll(function);
}
internal void AddFunctions(TexlFunctionSet functions)
{
Inc();
if (functions._count == 0)
{
return;
}
_functions.Add(functions);
// Add any associated enums
EnumStoreBuilder?.WithRequiredEnums(functions);
}
internal void AddFunction(TexlFunction function)
@ -223,7 +235,7 @@ namespace Microsoft.PowerFx
_functions.Add(function);
// Add any associated enums
EnumStoreBuilder?.WithRequiredEnums(new List<TexlFunction>() { function });
EnumStoreBuilder?.WithRequiredEnums(new TexlFunctionSet(function));
}
internal EnumStoreBuilder EnumStoreBuilder
@ -243,23 +255,11 @@ namespace Microsoft.PowerFx
if (entity is IExternalOptionSet optionSet)
{
nameInfo = new NameLookupInfo(
BindKind.OptionSet,
optionSet.Type,
DPath.Root,
0,
optionSet,
displayName);
nameInfo = new NameLookupInfo(BindKind.OptionSet, optionSet.Type, DPath.Root, 0, optionSet, displayName);
}
else if (entity is IExternalDataSource)
{
nameInfo = new NameLookupInfo(
BindKind.Data,
entity.Type,
DPath.Root,
0,
entity,
displayName);
nameInfo = new NameLookupInfo(BindKind.Data, entity.Type, DPath.Root, 0, entity, displayName);
}
else
{

Просмотреть файл

@ -1,12 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.UtilityDataStructures;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;

Просмотреть файл

@ -1,21 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.App;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Entities;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;
namespace Microsoft.PowerFx
{

Просмотреть файл

@ -9,6 +9,7 @@ using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Glue;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Intellisense;
@ -48,7 +49,7 @@ namespace Microsoft.PowerFx
// All functions that powerfx core knows about.
// Derived engines may only support a subset of these builtins,
// and they may add their own custom ones.
private static readonly ReadOnlySymbolTable _allBuiltinCoreFunctions = ReadOnlySymbolTable.NewDefault(Core.Texl.BuiltinFunctionsCore.BuiltinFunctionsLibrary);
private static readonly ReadOnlySymbolTable _allBuiltinCoreFunctions = ReadOnlySymbolTable.NewDefault(BuiltinFunctionsCore._library);
/// <summary>
/// Builtin functions supported by this engine.
@ -57,21 +58,29 @@ namespace Microsoft.PowerFx
// By default, we pull the core functions.
// These can be overridden.
internal IEnumerable<TexlFunction> Functions => CreateResolverInternal().Functions;
internal TexlFunctionSet Functions => CreateResolverInternal().Functions;
/// <summary>
/// Get all functions from the config and symbol tables.
/// </summary>
public IEnumerable<FunctionInfo> FunctionInfos => Functions.Select(f => new FunctionInfo(f));
/// </summary>
#pragma warning disable CS0618 // Type or member is obsolete
public IEnumerable<FunctionInfo> FunctionInfos => Functions.Functions.Select(f => new FunctionInfo(f));
#pragma warning restore CS0618 // Type or member is obsolete
/// <summary>
/// List all functions (both builtin and custom) registered with this evaluator.
/// </summary>
#pragma warning disable CA1024 // Use properties where appropriate
public IEnumerable<string> GetAllFunctionNames()
#pragma warning restore CA1024 // Use properties where appropriate
{
return FunctionInfos.Select(func => func.Name).Distinct();
return Functions.FunctionNames;
}
internal IEnumerable<TexlFunction> GetFunctionsByName(string name) => Functions.WithName(name);
internal int FunctionCount => Functions.Count();
// Additional symbols for the engine.
// A derived engine can replace this completely to inject engine-specific virtuals.
// These symbols then feed into the resolver

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Parser;
@ -154,8 +153,7 @@ namespace Microsoft.PowerFx.Intellisense
// Gets all functions by identifier (possible multiple results due to overloads).
private IEnumerable<TexlFunction> GetFunctionsByIdentifier(Identifier ident)
{
return _checkResult.Binding.NameResolver.Functions
.Where(fnc => fnc.Name == ident.Name && fnc.Namespace == ident.Namespace);
return _checkResult.Binding.NameResolver.Functions.WithName(ident.Name, ident.Namespace);
}
// Parse a function name string into an identifier (namespace and name).

Просмотреть файл

@ -5,7 +5,6 @@ using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Utils;
namespace Microsoft.PowerFx.Core.Texl
{
@ -13,217 +12,223 @@ namespace Microsoft.PowerFx.Core.Texl
// - no ControlInfo dependency
// - just functions that are ported over to Language.Core
internal class BuiltinFunctionsCore
{
public static IEnumerable<TexlFunction> BuiltinFunctionsLibrary => _library;
internal static IEnumerable<TexlFunction> TestOnly_AllBuiltinFunctions => _library.Concat(_featureGateFunctions);
{
// Functions in this list are shared and may show up in other hosts by default.
private static readonly List<TexlFunction> _library = new List<TexlFunction>(200);
private static readonly List<TexlFunction> _featureGateFunctions = new List<TexlFunction>();
internal static readonly TexlFunctionSet _library = new TexlFunctionSet();
private static readonly TexlFunctionSet _featureGateFunctions = new TexlFunctionSet();
public static readonly TexlFunction AmPm = _library.Append(new AmPmFunction());
public static readonly TexlFunction AmPmShort = _library.Append(new AmPmShortFunction());
public static readonly TexlFunction Abs = _library.Append(new AbsFunction());
public static readonly TexlFunction AbsT = _library.Append(new AbsTableFunction());
public static readonly TexlFunction Acos = _library.Append(new AcosFunction());
public static readonly TexlFunction AcosT = _library.Append(new AcosTableFunction());
public static readonly TexlFunction Acot = _library.Append(new AcotFunction());
public static readonly TexlFunction AcotT = _library.Append(new AcotTableFunction());
public static readonly TexlFunction AddColumns = _library.Append(new AddColumnsFunction());
public static readonly TexlFunction And = _library.Append(new VariadicLogicalFunction(isAnd: true));
public static readonly TexlFunction Asin = _library.Append(new AsinFunction());
public static readonly TexlFunction AsinT = _library.Append(new AsinTableFunction());
public static readonly TexlFunction AsType = _library.Append(new AsTypeFunction());
public static readonly TexlFunction Atan = _library.Append(new AtanFunction());
public static readonly TexlFunction AtanT = _library.Append(new AtanTableFunction());
public static readonly TexlFunction Atan2 = _library.Append(new Atan2Function());
public static readonly TexlFunction Average = _library.Append(new AverageFunction());
public static readonly TexlFunction AverageT = _library.Append(new AverageTableFunction());
public static readonly TexlFunction Blank = _library.Append(new BlankFunction());
public static readonly TexlFunction Boolean = _library.Append(new BooleanFunction());
public static readonly TexlFunction Boolean_T = _library.Append(new BooleanFunction_T());
public static readonly TexlFunction BooleanN = _library.Append(new BooleanNFunction());
public static readonly TexlFunction BooleanN_T = _library.Append(new BooleanNFunction_T());
public static readonly TexlFunction BooleanB = _library.Append(new BooleanBFunction());
public static readonly TexlFunction BooleanB_T = _library.Append(new BooleanBFunction_T());
public static readonly TexlFunction Boolean_UO = _library.Append(new BooleanFunction_UO());
public static readonly TexlFunction Clock24 = _library.Append(new IsClock24Function());
public static readonly TexlFunction Char = _library.Append(new CharFunction());
public static readonly TexlFunction CharT = _library.Append(new CharTFunction());
public static readonly TexlFunction Coalesce = _library.Append(new CoalesceFunction());
public static readonly TexlFunction ColorFade = _library.Append(new ColorFadeFunction());
public static readonly TexlFunction ColorFadeT = _library.Append(new ColorFadeTFunction());
public static readonly TexlFunction ColorValue = _library.Append(new ColorValueFunction());
public static readonly TexlFunction ColorValue_UO = _library.Append(new ColorValueFunction_UO());
public static readonly TexlFunction Concat = _library.Append(new ConcatFunction());
public static readonly TexlFunction Concatenate = _library.Append(new ConcatenateFunction());
public static readonly TexlFunction ConcatenateT = _library.Append(new ConcatenateTableFunction());
public static readonly TexlFunction Cos = _library.Append(new CosFunction());
public static readonly TexlFunction CosT = _library.Append(new CosTableFunction());
public static readonly TexlFunction Cot = _library.Append(new CotFunction());
public static readonly TexlFunction CotT = _library.Append(new CotTableFunction());
public static readonly TexlFunction Count = _library.Append(new CountFunction());
public static readonly TexlFunction CountA = _library.Append(new CountAFunction());
public static readonly TexlFunction CountIf = _library.Append(new CountIfFunction());
public static readonly TexlFunction CountRows = _library.Append(new CountRowsFunction());
public static readonly TexlFunction CountRows_UO = _library.Append(new CountRowsFunction_UO());
public static readonly TexlFunction Date = _library.Append(new DateFunction());
public static readonly TexlFunction DateAdd = _library.Append(new DateAddFunction());
public static readonly TexlFunction DateAddT = _library.Append(new DateAddTFunction());
public static readonly TexlFunction DateDiff = _library.Append(new DateDiffFunction());
public static readonly TexlFunction DateDiffT = _library.Append(new DateDiffTFunction());
public static readonly TexlFunction DateTime = _library.Append(new DateTimeFunction());
public static readonly TexlFunction DateTimeValue = _library.Append(new DateTimeValueFunction());
public static readonly TexlFunction DateTimeValue_UO = _library.Append(new DateTimeValueFunction_UO());
public static readonly TexlFunction DateValue = _library.Append(new DateValueFunction());
public static readonly TexlFunction DateValue_UO = _library.Append(new DateValueFunction_UO());
public static readonly TexlFunction Day = _library.Append(new DayFunction());
public static readonly TexlFunction Dec2Hex = _library.Append(new Dec2HexFunction());
public static readonly TexlFunction Dec2HexT = _library.Append(new Dec2HexTFunction());
public static readonly TexlFunction Degrees = _library.Append(new DegreesFunction());
public static readonly TexlFunction DegreesT = _library.Append(new DegreesTableFunction());
public static readonly TexlFunction DropColumns = _library.Append(new DropColumnsFunction());
public static readonly TexlFunction EndsWith = _library.Append(new EndsWithFunction());
public static readonly TexlFunction Error = _library.Append(new ErrorFunction());
public static readonly TexlFunction Exp = _library.Append(new ExpFunction());
public static readonly TexlFunction ExpT = _library.Append(new ExpTableFunction());
public static readonly TexlFunction Filter = _library.Append(new FilterFunction());
public static readonly TexlFunction Find = _library.Append(new FindFunction());
public static readonly TexlFunction FindT = _library.Append(new FindTFunction());
public static readonly TexlFunction First = _library.Append(new FirstLastFunction(isFirst: true));
public static readonly TexlFunction FirstN = _library.Append(new FirstLastNFunction(isFirst: true));
public static readonly TexlFunction First_UO = _library.Append(new FirstLastFunction_UO(isFirst: true));
public static readonly TexlFunction FirstN_UO = _library.Append(new FirstLastNFunction_UO(isFirst: true));
public static readonly TexlFunction ForAll = _library.Append(new ForAllFunction());
public static readonly TexlFunction ForAll_UO = _library.Append(new ForAllFunction_UO());
public static readonly TexlFunction GUIDPure = _library.Append(new GUIDPureFunction());
public static readonly TexlFunction GUID_UO = _library.Append(new GUIDPureFunction_UO());
public static readonly TexlFunction Hex2Dec = _library.Append(new Hex2DecFunction());
public static readonly TexlFunction Hex2DecT = _library.Append(new Hex2DecTFunction());
public static readonly TexlFunction Hour = _library.Append(new HourFunction());
public static readonly TexlFunction If = _library.Append(new IfFunction());
public static readonly TexlFunction IfError = _library.Append(new IfErrorFunction());
public static readonly TexlFunction Index = _library.Append(new IndexFunction());
public static readonly TexlFunction Index_UO = _library.Append(new IndexFunction_UO());
public static readonly TexlFunction Int = _library.Append(new IntFunction());
public static readonly TexlFunction IntT = _library.Append(new IntTableFunction());
public static readonly TexlFunction IsBlank = _library.Append(new IsBlankFunction());
public static readonly TexlFunction IsBlankOptionSetValue = _library.Append(new IsBlankOptionSetValueFunction());
public static readonly TexlFunction IsBlankOrError = _library.Append(new IsBlankOrErrorFunction());
public static readonly TexlFunction IsBlankOrErrorOptionSetValue = _library.Append(new IsBlankOrErrorOptionSetValueFunction());
public static readonly TexlFunction IsEmpty = _library.Append(new IsEmptyFunction());
public static readonly TexlFunction IsError = _library.Append(new IsErrorFunction());
public static readonly TexlFunction IsToday = _library.Append(new IsTodayFunction());
public static readonly TexlFunction IsNumeric = _library.Append(new IsNumericFunction());
public static readonly TexlFunction ISOWeekNum = _library.Append(new ISOWeekNumFunction());
public static readonly TexlFunction Last = _library.Append(new FirstLastFunction(isFirst: false));
public static readonly TexlFunction LastN = _library.Append(new FirstLastNFunction(isFirst: false));
public static readonly TexlFunction Last_UO = _library.Append(new FirstLastFunction_UO(isFirst: false));
public static readonly TexlFunction LastN_UO = _library.Append(new FirstLastNFunction_UO(isFirst: false));
public static readonly TexlFunction Left = _library.Append(new LeftRightScalarFunction(isLeft: true));
public static readonly TexlFunction LeftTS = _library.Append(new LeftRightTableScalarFunction(isLeft: true));
public static readonly TexlFunction LeftTT = _library.Append(new LeftRightTableTableFunction(isLeft: true));
public static readonly TexlFunction LeftST = _library.Append(new LeftRightScalarTableFunction(isLeft: true));
public static readonly TexlFunction Len = _library.Append(new LenFunction());
public static readonly TexlFunction LenT = _library.Append(new LenTFunction());
public static readonly TexlFunction Ln = _library.Append(new LnFunction());
public static readonly TexlFunction LnT = _library.Append(new LnTableFunction());
public static readonly TexlFunction Log = _library.Append(new LogFunction());
public static readonly TexlFunction LogT = _library.Append(new LogTFunction());
public static readonly TexlFunction LookUp = _library.Append(new LookUpFunction());
public static readonly TexlFunction Lower = _library.Append(new LowerUpperFunction(isLower: true));
public static readonly TexlFunction LowerT = _library.Append(new LowerUpperTFunction(isLower: true));
public static readonly TexlFunction Max = _library.Append(new MinMaxFunction(isMin: false));
public static readonly TexlFunction MaxT = _library.Append(new MinMaxTableFunction(isMin: false));
public static readonly TexlFunction Mid = _library.Append(new MidFunction());
public static readonly TexlFunction MidT = _library.Append(new MidTFunction());
public static readonly TexlFunction Min = _library.Append(new MinMaxFunction(isMin: true));
public static readonly TexlFunction MinT = _library.Append(new MinMaxTableFunction(isMin: true));
public static readonly TexlFunction Minute = _library.Append(new MinuteFunction());
public static readonly TexlFunction Mod = _library.Append(new ModFunction());
public static readonly TexlFunction ModT = _library.Append(new ModTFunction());
public static readonly TexlFunction Month = _library.Append(new MonthFunction());
public static readonly TexlFunction MonthsLong = _library.Append(new MonthsLongFunction());
public static readonly TexlFunction MonthsShort = _library.Append(new MonthsShortFunction());
public static readonly TexlFunction Not = _library.Append(new NotFunction());
public static readonly TexlFunction Now = _library.Append(new NowFunction());
public static readonly TexlFunction OptionsSetInfo = _featureGateFunctions.Append(new OptionSetInfoFunction());
public static readonly TexlFunction Or = _library.Append(new VariadicLogicalFunction(isAnd: false));
public static readonly TexlFunction ParseJSON = _library.Append(new ParseJSONFunction());
public static readonly TexlFunction Power = _library.Append(new PowerFunction());
public static readonly TexlFunction PowerT = _library.Append(new PowerTFunction());
public static readonly TexlFunction Pi = _library.Append(new PiFunction());
public static readonly TexlFunction Proper = _library.Append(new ProperFunction());
public static readonly TexlFunction ProperT = _library.Append(new ProperTFunction());
public static readonly TexlFunction Radians = _library.Append(new RadiansFunction());
public static readonly TexlFunction RadiansT = _library.Append(new RadiansTableFunction());
public static readonly TexlFunction Rand = _library.Append(new RandFunction());
public static readonly TexlFunction RandBetween = _library.Append(new RandBetweenFunction());
public static readonly TexlFunction Replace = _library.Append(new ReplaceFunction());
public static readonly TexlFunction ReplaceT = _library.Append(new ReplaceTFunction());
public static readonly TexlFunction RGBA = _library.Append(new RGBAFunction());
public static readonly TexlFunction Right = _library.Append(new LeftRightScalarFunction(isLeft: false));
public static readonly TexlFunction RightTS = _library.Append(new LeftRightTableScalarFunction(isLeft: false));
public static readonly TexlFunction RightTT = _library.Append(new LeftRightTableTableFunction(isLeft: false));
public static readonly TexlFunction RightST = _library.Append(new LeftRightScalarTableFunction(isLeft: false));
public static readonly TexlFunction Round = _library.Append(new RoundScalarFunction());
public static readonly TexlFunction RoundT = _library.Append(new RoundTableFunction());
public static readonly TexlFunction RoundDown = _library.Append(new RoundDownScalarFunction());
public static readonly TexlFunction RoundDownT = _library.Append(new RoundDownTableFunction());
public static readonly TexlFunction RoundUp = _library.Append(new RoundUpScalarFunction());
public static readonly TexlFunction RoundUpT = _library.Append(new RoundUpTableFunction());
public static readonly TexlFunction Second = _library.Append(new SecondFunction());
public static readonly TexlFunction Sequence = _library.Append(new SequenceFunction());
public static readonly TexlFunction Shuffle = _library.Append(new ShuffleFunction());
public static readonly TexlFunction Sin = _library.Append(new SinFunction());
public static readonly TexlFunction Sort = _library.Append(new SortFunction());
public static readonly TexlFunction SortByColumns = _library.Append(new SortByColumnsFunction());
public static readonly TexlFunction SortByColumnsOrderTable = _library.Append(new SortByColumnsOrderTableFunction());
public static readonly TexlFunction SinT = _library.Append(new SinTableFunction());
public static readonly TexlFunction Split = _library.Append(new SplitFunction());
public static readonly TexlFunction Sqrt = _library.Append(new SqrtFunction());
public static readonly TexlFunction SqrtT = _library.Append(new SqrtTableFunction());
public static readonly TexlFunction StartsWith = _library.Append(new StartsWithFunction());
public static readonly TexlFunction StdevP = _library.Append(new StdevPFunction());
public static readonly TexlFunction StdevPT = _library.Append(new StdevPTableFunction());
public static readonly TexlFunction Substitute = _library.Append(new SubstituteFunction());
public static readonly TexlFunction SubstituteT = _library.Append(new SubstituteTFunction());
public static readonly TexlFunction Sum = _library.Append(new SumFunction());
public static readonly TexlFunction SumT = _library.Append(new SumTableFunction());
public static readonly TexlFunction Switch = _library.Append(new SwitchFunction());
public static readonly TexlFunction Table = _library.Append(new TableFunction());
public static readonly TexlFunction Table_UO = _library.Append(new TableFunction_UO());
public static readonly TexlFunction Tan = _library.Append(new TanFunction());
public static readonly TexlFunction TanT = _library.Append(new TanTableFunction());
public static readonly TexlFunction Time = _library.Append(new TimeFunction());
public static readonly TexlFunction TimeValue = _library.Append(new TimeValueFunction());
public static readonly TexlFunction TimeValue_UO = _library.Append(new TimeValueFunction_UO());
public static readonly TexlFunction TimeZoneOffset = _library.Append(new TimeZoneOffsetFunction());
public static readonly TexlFunction Today = _library.Append(new TodayFunction());
public static readonly TexlFunction Trim = _library.Append(new TrimFunction());
public static readonly TexlFunction TrimT = _library.Append(new TrimTFunction());
public static readonly TexlFunction TrimEnds = _library.Append(new TrimEndsFunction());
public static readonly TexlFunction TrimEndsT = _library.Append(new TrimEndsTFunction());
public static readonly TexlFunction Trunc = _library.Append(new TruncFunction());
public static readonly TexlFunction TruncT = _library.Append(new TruncTableFunction());
public static readonly TexlFunction Upper = _library.Append(new LowerUpperFunction(isLower: false));
public static readonly TexlFunction UpperT = _library.Append(new LowerUpperTFunction(isLower: false));
public static readonly TexlFunction Value = _library.Append(new ValueFunction());
public static readonly TexlFunction Value_UO = _library.Append(new ValueFunction_UO());
public static readonly TexlFunction VarP = _library.Append(new VarPFunction());
public static readonly TexlFunction VarPT = _library.Append(new VarPTableFunction());
public static readonly TexlFunction Text = _library.Append(new TextFunction());
public static readonly TexlFunction Text_UO = _library.Append(new TextFunction_UO());
public static readonly TexlFunction Weekday = _library.Append(new WeekdayFunction());
public static readonly TexlFunction WeekdaysLong = _library.Append(new WeekdaysLongFunction());
public static readonly TexlFunction WeekdaysShort = _library.Append(new WeekdaysShortFunction());
public static readonly TexlFunction WeekNum = _library.Append(new WeekNumFunction());
public static readonly TexlFunction With = _library.Append(new WithFunction());
public static readonly TexlFunction Year = _library.Append(new YearFunction());
public static readonly TexlFunction AmPm = _library.Add(new AmPmFunction());
public static readonly TexlFunction AmPmShort = _library.Add(new AmPmShortFunction());
public static readonly TexlFunction Abs = _library.Add(new AbsFunction());
public static readonly TexlFunction AbsT = _library.Add(new AbsTableFunction());
public static readonly TexlFunction Acos = _library.Add(new AcosFunction());
public static readonly TexlFunction AcosT = _library.Add(new AcosTableFunction());
public static readonly TexlFunction Acot = _library.Add(new AcotFunction());
public static readonly TexlFunction AcotT = _library.Add(new AcotTableFunction());
public static readonly TexlFunction AddColumns = _library.Add(new AddColumnsFunction());
public static readonly TexlFunction And = _library.Add(new VariadicLogicalFunction(isAnd: true));
public static readonly TexlFunction Asin = _library.Add(new AsinFunction());
public static readonly TexlFunction AsinT = _library.Add(new AsinTableFunction());
public static readonly TexlFunction AsType = _library.Add(new AsTypeFunction());
public static readonly TexlFunction Atan = _library.Add(new AtanFunction());
public static readonly TexlFunction AtanT = _library.Add(new AtanTableFunction());
public static readonly TexlFunction Atan2 = _library.Add(new Atan2Function());
public static readonly TexlFunction Average = _library.Add(new AverageFunction());
public static readonly TexlFunction AverageT = _library.Add(new AverageTableFunction());
public static readonly TexlFunction Blank = _library.Add(new BlankFunction());
public static readonly TexlFunction Boolean = _library.Add(new BooleanFunction());
public static readonly TexlFunction Boolean_T = _library.Add(new BooleanFunction_T());
public static readonly TexlFunction BooleanN = _library.Add(new BooleanNFunction());
public static readonly TexlFunction BooleanN_T = _library.Add(new BooleanNFunction_T());
public static readonly TexlFunction BooleanB = _library.Add(new BooleanBFunction());
public static readonly TexlFunction BooleanB_T = _library.Add(new BooleanBFunction_T());
public static readonly TexlFunction Boolean_UO = _library.Add(new BooleanFunction_UO());
public static readonly TexlFunction Clock24 = _library.Add(new IsClock24Function());
public static readonly TexlFunction Char = _library.Add(new CharFunction());
public static readonly TexlFunction CharT = _library.Add(new CharTFunction());
public static readonly TexlFunction Coalesce = _library.Add(new CoalesceFunction());
public static readonly TexlFunction ColorFade = _library.Add(new ColorFadeFunction());
public static readonly TexlFunction ColorFadeT = _library.Add(new ColorFadeTFunction());
public static readonly TexlFunction ColorValue = _library.Add(new ColorValueFunction());
public static readonly TexlFunction ColorValue_UO = _library.Add(new ColorValueFunction_UO());
public static readonly TexlFunction Concat = _library.Add(new ConcatFunction());
public static readonly TexlFunction Concatenate = _library.Add(new ConcatenateFunction());
public static readonly TexlFunction ConcatenateT = _library.Add(new ConcatenateTableFunction());
public static readonly TexlFunction Cos = _library.Add(new CosFunction());
public static readonly TexlFunction CosT = _library.Add(new CosTableFunction());
public static readonly TexlFunction Cot = _library.Add(new CotFunction());
public static readonly TexlFunction CotT = _library.Add(new CotTableFunction());
public static readonly TexlFunction Count = _library.Add(new CountFunction());
public static readonly TexlFunction CountA = _library.Add(new CountAFunction());
public static readonly TexlFunction CountIf = _library.Add(new CountIfFunction());
public static readonly TexlFunction CountRows = _library.Add(new CountRowsFunction());
public static readonly TexlFunction CountRows_UO = _library.Add(new CountRowsFunction_UO());
public static readonly TexlFunction Date = _library.Add(new DateFunction());
public static readonly TexlFunction DateAdd = _library.Add(new DateAddFunction());
public static readonly TexlFunction DateAddT = _library.Add(new DateAddTFunction());
public static readonly TexlFunction DateDiff = _library.Add(new DateDiffFunction());
public static readonly TexlFunction DateDiffT = _library.Add(new DateDiffTFunction());
public static readonly TexlFunction DateTime = _library.Add(new DateTimeFunction());
public static readonly TexlFunction DateTimeValue = _library.Add(new DateTimeValueFunction());
public static readonly TexlFunction DateTimeValue_UO = _library.Add(new DateTimeValueFunction_UO());
public static readonly TexlFunction DateValue = _library.Add(new DateValueFunction());
public static readonly TexlFunction DateValue_UO = _library.Add(new DateValueFunction_UO());
public static readonly TexlFunction Day = _library.Add(new DayFunction());
public static readonly TexlFunction Dec2Hex = _library.Add(new Dec2HexFunction());
public static readonly TexlFunction Dec2HexT = _library.Add(new Dec2HexTFunction());
public static readonly TexlFunction Degrees = _library.Add(new DegreesFunction());
public static readonly TexlFunction DegreesT = _library.Add(new DegreesTableFunction());
public static readonly TexlFunction DropColumns = _library.Add(new DropColumnsFunction());
public static readonly TexlFunction EndsWith = _library.Add(new EndsWithFunction());
public static readonly TexlFunction Error = _library.Add(new ErrorFunction());
public static readonly TexlFunction Exp = _library.Add(new ExpFunction());
public static readonly TexlFunction ExpT = _library.Add(new ExpTableFunction());
public static readonly TexlFunction Filter = _library.Add(new FilterFunction());
public static readonly TexlFunction Find = _library.Add(new FindFunction());
public static readonly TexlFunction FindT = _library.Add(new FindTFunction());
public static readonly TexlFunction First = _library.Add(new FirstLastFunction(isFirst: true));
public static readonly TexlFunction FirstN = _library.Add(new FirstLastNFunction(isFirst: true));
public static readonly TexlFunction First_UO = _library.Add(new FirstLastFunction_UO(isFirst: true));
public static readonly TexlFunction FirstN_UO = _library.Add(new FirstLastNFunction_UO(isFirst: true));
public static readonly TexlFunction ForAll = _library.Add(new ForAllFunction());
public static readonly TexlFunction ForAll_UO = _library.Add(new ForAllFunction_UO());
public static readonly TexlFunction GUIDPure = _library.Add(new GUIDPureFunction());
public static readonly TexlFunction GUID_UO = _library.Add(new GUIDPureFunction_UO());
public static readonly TexlFunction Hex2Dec = _library.Add(new Hex2DecFunction());
public static readonly TexlFunction Hex2DecT = _library.Add(new Hex2DecTFunction());
public static readonly TexlFunction Hour = _library.Add(new HourFunction());
public static readonly TexlFunction If = _library.Add(new IfFunction());
public static readonly TexlFunction IfError = _library.Add(new IfErrorFunction());
public static readonly TexlFunction Index = _library.Add(new IndexFunction());
public static readonly TexlFunction Index_UO = _library.Add(new IndexFunction_UO());
public static readonly TexlFunction Int = _library.Add(new IntFunction());
public static readonly TexlFunction IntT = _library.Add(new IntTableFunction());
public static readonly TexlFunction IsBlank = _library.Add(new IsBlankFunction());
public static readonly TexlFunction IsBlankOptionSetValue = _library.Add(new IsBlankOptionSetValueFunction());
public static readonly TexlFunction IsBlankOrError = _library.Add(new IsBlankOrErrorFunction());
public static readonly TexlFunction IsBlankOrErrorOptionSetValue = _library.Add(new IsBlankOrErrorOptionSetValueFunction());
public static readonly TexlFunction IsEmpty = _library.Add(new IsEmptyFunction());
public static readonly TexlFunction IsError = _library.Add(new IsErrorFunction());
public static readonly TexlFunction IsToday = _library.Add(new IsTodayFunction());
public static readonly TexlFunction IsNumeric = _library.Add(new IsNumericFunction());
public static readonly TexlFunction ISOWeekNum = _library.Add(new ISOWeekNumFunction());
public static readonly TexlFunction Last = _library.Add(new FirstLastFunction(isFirst: false));
public static readonly TexlFunction LastN = _library.Add(new FirstLastNFunction(isFirst: false));
public static readonly TexlFunction Last_UO = _library.Add(new FirstLastFunction_UO(isFirst: false));
public static readonly TexlFunction LastN_UO = _library.Add(new FirstLastNFunction_UO(isFirst: false));
public static readonly TexlFunction Left = _library.Add(new LeftRightScalarFunction(isLeft: true));
public static readonly TexlFunction LeftTS = _library.Add(new LeftRightTableScalarFunction(isLeft: true));
public static readonly TexlFunction LeftTT = _library.Add(new LeftRightTableTableFunction(isLeft: true));
public static readonly TexlFunction LeftST = _library.Add(new LeftRightScalarTableFunction(isLeft: true));
public static readonly TexlFunction Len = _library.Add(new LenFunction());
public static readonly TexlFunction LenT = _library.Add(new LenTFunction());
public static readonly TexlFunction Ln = _library.Add(new LnFunction());
public static readonly TexlFunction LnT = _library.Add(new LnTableFunction());
public static readonly TexlFunction Log = _library.Add(new LogFunction());
public static readonly TexlFunction LogT = _library.Add(new LogTFunction());
public static readonly TexlFunction LookUp = _library.Add(new LookUpFunction());
public static readonly TexlFunction Lower = _library.Add(new LowerUpperFunction(isLower: true));
public static readonly TexlFunction LowerT = _library.Add(new LowerUpperTFunction(isLower: true));
public static readonly TexlFunction Max = _library.Add(new MinMaxFunction(isMin: false));
public static readonly TexlFunction MaxT = _library.Add(new MinMaxTableFunction(isMin: false));
public static readonly TexlFunction Mid = _library.Add(new MidFunction());
public static readonly TexlFunction MidT = _library.Add(new MidTFunction());
public static readonly TexlFunction Min = _library.Add(new MinMaxFunction(isMin: true));
public static readonly TexlFunction MinT = _library.Add(new MinMaxTableFunction(isMin: true));
public static readonly TexlFunction Minute = _library.Add(new MinuteFunction());
public static readonly TexlFunction Mod = _library.Add(new ModFunction());
public static readonly TexlFunction ModT = _library.Add(new ModTFunction());
public static readonly TexlFunction Month = _library.Add(new MonthFunction());
public static readonly TexlFunction MonthsLong = _library.Add(new MonthsLongFunction());
public static readonly TexlFunction MonthsShort = _library.Add(new MonthsShortFunction());
public static readonly TexlFunction Not = _library.Add(new NotFunction());
public static readonly TexlFunction Now = _library.Add(new NowFunction());
public static readonly TexlFunction OptionsSetInfo = _featureGateFunctions.Add(new OptionSetInfoFunction());
public static readonly TexlFunction Or = _library.Add(new VariadicLogicalFunction(isAnd: false));
public static readonly TexlFunction ParseJSON = _library.Add(new ParseJSONFunction());
public static readonly TexlFunction Power = _library.Add(new PowerFunction());
public static readonly TexlFunction PowerT = _library.Add(new PowerTFunction());
public static readonly TexlFunction Pi = _library.Add(new PiFunction());
public static readonly TexlFunction Proper = _library.Add(new ProperFunction());
public static readonly TexlFunction ProperT = _library.Add(new ProperTFunction());
public static readonly TexlFunction Radians = _library.Add(new RadiansFunction());
public static readonly TexlFunction RadiansT = _library.Add(new RadiansTableFunction());
public static readonly TexlFunction Rand = _library.Add(new RandFunction());
public static readonly TexlFunction RandBetween = _library.Add(new RandBetweenFunction());
public static readonly TexlFunction Replace = _library.Add(new ReplaceFunction());
public static readonly TexlFunction ReplaceT = _library.Add(new ReplaceTFunction());
public static readonly TexlFunction RGBA = _library.Add(new RGBAFunction());
public static readonly TexlFunction Right = _library.Add(new LeftRightScalarFunction(isLeft: false));
public static readonly TexlFunction RightTS = _library.Add(new LeftRightTableScalarFunction(isLeft: false));
public static readonly TexlFunction RightTT = _library.Add(new LeftRightTableTableFunction(isLeft: false));
public static readonly TexlFunction RightST = _library.Add(new LeftRightScalarTableFunction(isLeft: false));
public static readonly TexlFunction Round = _library.Add(new RoundScalarFunction());
public static readonly TexlFunction RoundT = _library.Add(new RoundTableFunction());
public static readonly TexlFunction RoundDown = _library.Add(new RoundDownScalarFunction());
public static readonly TexlFunction RoundDownT = _library.Add(new RoundDownTableFunction());
public static readonly TexlFunction RoundUp = _library.Add(new RoundUpScalarFunction());
public static readonly TexlFunction RoundUpT = _library.Add(new RoundUpTableFunction());
public static readonly TexlFunction Second = _library.Add(new SecondFunction());
public static readonly TexlFunction Sequence = _library.Add(new SequenceFunction());
public static readonly TexlFunction Shuffle = _library.Add(new ShuffleFunction());
public static readonly TexlFunction Sin = _library.Add(new SinFunction());
public static readonly TexlFunction Sort = _library.Add(new SortFunction());
public static readonly TexlFunction SortByColumns = _library.Add(new SortByColumnsFunction());
public static readonly TexlFunction SortByColumnsOrderTable = _library.Add(new SortByColumnsOrderTableFunction());
public static readonly TexlFunction SinT = _library.Add(new SinTableFunction());
public static readonly TexlFunction Split = _library.Add(new SplitFunction());
public static readonly TexlFunction Sqrt = _library.Add(new SqrtFunction());
public static readonly TexlFunction SqrtT = _library.Add(new SqrtTableFunction());
public static readonly TexlFunction StartsWith = _library.Add(new StartsWithFunction());
public static readonly TexlFunction StdevP = _library.Add(new StdevPFunction());
public static readonly TexlFunction StdevPT = _library.Add(new StdevPTableFunction());
public static readonly TexlFunction Substitute = _library.Add(new SubstituteFunction());
public static readonly TexlFunction SubstituteT = _library.Add(new SubstituteTFunction());
public static readonly TexlFunction Sum = _library.Add(new SumFunction());
public static readonly TexlFunction SumT = _library.Add(new SumTableFunction());
public static readonly TexlFunction Switch = _library.Add(new SwitchFunction());
public static readonly TexlFunction Table = _library.Add(new TableFunction());
public static readonly TexlFunction Table_UO = _library.Add(new TableFunction_UO());
public static readonly TexlFunction Tan = _library.Add(new TanFunction());
public static readonly TexlFunction TanT = _library.Add(new TanTableFunction());
public static readonly TexlFunction Time = _library.Add(new TimeFunction());
public static readonly TexlFunction TimeValue = _library.Add(new TimeValueFunction());
public static readonly TexlFunction TimeValue_UO = _library.Add(new TimeValueFunction_UO());
public static readonly TexlFunction TimeZoneOffset = _library.Add(new TimeZoneOffsetFunction());
public static readonly TexlFunction Today = _library.Add(new TodayFunction());
public static readonly TexlFunction Trim = _library.Add(new TrimFunction());
public static readonly TexlFunction TrimT = _library.Add(new TrimTFunction());
public static readonly TexlFunction TrimEnds = _library.Add(new TrimEndsFunction());
public static readonly TexlFunction TrimEndsT = _library.Add(new TrimEndsTFunction());
public static readonly TexlFunction Trunc = _library.Add(new TruncFunction());
public static readonly TexlFunction TruncT = _library.Add(new TruncTableFunction());
public static readonly TexlFunction Upper = _library.Add(new LowerUpperFunction(isLower: false));
public static readonly TexlFunction UpperT = _library.Add(new LowerUpperTFunction(isLower: false));
public static readonly TexlFunction Value = _library.Add(new ValueFunction());
public static readonly TexlFunction Value_UO = _library.Add(new ValueFunction_UO());
public static readonly TexlFunction VarP = _library.Add(new VarPFunction());
public static readonly TexlFunction VarPT = _library.Add(new VarPTableFunction());
public static readonly TexlFunction Text = _library.Add(new TextFunction());
public static readonly TexlFunction Text_UO = _library.Add(new TextFunction_UO());
public static readonly TexlFunction Weekday = _library.Add(new WeekdayFunction());
public static readonly TexlFunction WeekdaysLong = _library.Add(new WeekdaysLongFunction());
public static readonly TexlFunction WeekdaysShort = _library.Add(new WeekdaysShortFunction());
public static readonly TexlFunction WeekNum = _library.Add(new WeekNumFunction());
public static readonly TexlFunction With = _library.Add(new WithFunction());
public static readonly TexlFunction Year = _library.Add(new YearFunction());
public static readonly TexlFunction IsUTCToday = _featureGateFunctions.Append(new IsUTCTodayFunction());
public static readonly TexlFunction UTCNow = _featureGateFunctions.Append(new UTCNowFunction());
public static readonly TexlFunction UTCToday = _featureGateFunctions.Append(new UTCTodayFunction());
public static readonly TexlFunction IsUTCToday = _featureGateFunctions.Add(new IsUTCTodayFunction());
public static readonly TexlFunction UTCNow = _featureGateFunctions.Add(new UTCNowFunction());
public static readonly TexlFunction UTCToday = _featureGateFunctions.Add(new UTCTodayFunction());
// Slow API, only use for backward compatibility
#pragma warning disable CS0618 // Type or member is obsolete
public static IEnumerable<TexlFunction> BuiltinFunctionsLibrary => _library.Functions;
private static readonly TexlFunctionSet _testOnlyLibrary = new TexlFunctionSet(_library.Functions).Add(_featureGateFunctions);
// Slow API, only use for backward compatibility
internal static IEnumerable<TexlFunction> TestOnly_AllBuiltinFunctions => _testOnlyLibrary.Functions;
#pragma warning restore CS0618 // Type or member is obsolete
}
}

Просмотреть файл

@ -622,7 +622,9 @@ namespace Microsoft.PowerFx.Intellisense
// TASK: 76039: Intellisense: Update intellisense to filter suggestions based on the expected type of the text being typed in UI
Contracts.AssertValue(intellisenseData);
foreach (var function in intellisenseData.Binding.NameResolver.Functions)
// $$$ Needs optimization
#pragma warning disable CS0618 // Type or member is obsolete
foreach (var function in intellisenseData.Binding.NameResolver.Functions.Functions)
{
var qualifiedName = function.QualifiedName;
var highlightStart = qualifiedName.IndexOf(intellisenseData.MatchingStr, StringComparison.OrdinalIgnoreCase);
@ -639,6 +641,7 @@ namespace Microsoft.PowerFx.Intellisense
}
}
}
#pragma warning restore CS0618 // Type or member is obsolete
}
/// <summary>
@ -702,9 +705,8 @@ namespace Microsoft.PowerFx.Intellisense
intellisenseData.AddCustomSuggestionsForGlobals();
// Suggest function namespaces
var namespaces = intellisenseData.Binding.NameResolver.Functions.Select(func => func.Namespace).Distinct();
foreach (var funcNamespace in namespaces)
// Suggest function namespaces
foreach (var funcNamespace in intellisenseData.Binding.NameResolver.Functions.Namespaces)
{
if (funcNamespace == DPath.Root)
{

Просмотреть файл

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Linq;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Syntax;
@ -48,7 +47,7 @@ namespace Microsoft.PowerFx.Intellisense
// Cursor is in the head.
// Suggest function names.
// Get the matching string as a substring from the script so that the whitespace is preserved.
var replacementLength = IntellisenseHelper.GetReplacementLength(intellisenseData, spanMin, spanLim, intellisenseData.Binding.NameResolver.Functions.Select(function => function.Name));
var replacementLength = IntellisenseHelper.GetReplacementLength(intellisenseData, spanMin, spanLim, intellisenseData.Binding.NameResolver.Functions.FunctionNames);
// If we are replacing the full token, also include the opening paren (since this will be provided by the suggestion)
if (replacementLength == spanLim - spanMin)

Просмотреть файл

@ -160,7 +160,7 @@ namespace Microsoft.PowerFx.Intellisense
return data.TryGetEnumSymbol(firstNameInfo.Name, binding, out enumSymbol);
}
private static bool TryGetNamespaceFunctions(TexlNode node, TexlBinding binding, out IEnumerable<TexlFunction> functions)
{
Contracts.AssertValue(node);

Просмотреть файл

@ -291,18 +291,15 @@ namespace Microsoft.PowerFx.Core.Types.Enums
private Dictionary<string, DType> _enumTypes;
#region Internal methods
internal EnumStoreBuilder WithRequiredEnums(IEnumerable<TexlFunction> functions)
internal EnumStoreBuilder WithRequiredEnums(TexlFunctionSet functions)
{
var missingEnums = new Dictionary<string, string>();
foreach (var function in functions)
foreach (var name in functions.Enums)
{
var requiredEnumNames = function.GetRequiredEnumNames();
foreach (var name in requiredEnumNames)
if (!_workingEnums.ContainsKey(name) && !missingEnums.ContainsKey(name))
{
if (!_workingEnums.ContainsKey(name) && !missingEnums.ContainsKey(name))
{
missingEnums.Add(name, DefaultEnums[name]);
}
missingEnums.Add(name, DefaultEnums[name]);
}
}

Просмотреть файл

@ -143,6 +143,8 @@ namespace Microsoft.PowerFx.Core.Utils
return false;
}
// $$$ Needs optimization $$$
/// <summary>
/// Takes a name and makes it into a valid <see cref="DName" />.
/// If the name contains all spaces, an underscore is prepended to the name.
@ -161,9 +163,10 @@ namespace Microsoft.PowerFx.Core.Utils
var fAllSpaces = true;
var fHasDisallowedWhiteSpaceCharacters = false;
fModified = false;
// $$$ Needs optimization
for (var i = 0; i < strName.Length; i++)
{
var fIsSpace = strName[i] == ChSpace;

Просмотреть файл

@ -49,10 +49,12 @@ namespace Microsoft.PowerFx.Core.Utils
if (flags.HasFlag(GetTokensFlags.AllFunctions))
{
foreach (var item in binding.NameResolver.Functions)
#pragma warning disable CS0618 // Type or member is obsolete
foreach (var item in binding.NameResolver.Functions.Functions)
{
tokens[item.QualifiedName] = TokenResultType.Function;
}
#pragma warning restore CS0618 // Type or member is obsolete
}
return tokens;

Просмотреть файл

@ -1,14 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.IR.Nodes;
using Microsoft.PowerFx.Core.Public;
using Microsoft.PowerFx.Intellisense;
using Microsoft.PowerFx.Syntax;
using Microsoft.PowerFx.Types;
@ -58,13 +55,14 @@ namespace Microsoft.PowerFx
if (symbolTable.Functions.Any())
{
tw.WriteLine();
tw.WriteLine($"{indent} Functions ({symbolTable.Functions.Count()}) total:");
foreach (var func in symbolTable.Functions)
tw.WriteLine($"{indent} Functions ({symbolTable.Functions.Count()}) total:");
foreach (var funcName in symbolTable.Functions.FunctionNames)
{
tw.WriteLine($"{indent} {func.Name}");
tw.WriteLine($"{indent} {funcName}");
}
}
}
}
tw.WriteLine();
}
@ -111,12 +109,12 @@ namespace Microsoft.PowerFx
{
var settings = new FormulaValueSerializerSettings
{
UseCompactRepresentation = true
UseCompactRepresentation = true
};
var sb = new StringBuilder();
value.ToExpression(sb, settings);
return sb.ToString();
}
}
public static string Dump(TexlNode parseNode)
{

Просмотреть файл

@ -16,7 +16,7 @@ using Microsoft.PowerFx.Core.IR.Nodes;
using Microsoft.PowerFx.Core.IR.Symbols;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Functions;
using Microsoft.PowerFx.Interpreter;
using Microsoft.PowerFx.Interpreter;
using Microsoft.PowerFx.Interpreter.Exceptions;
using Microsoft.PowerFx.Types;
using static Microsoft.PowerFx.Functions.Library;
@ -67,7 +67,7 @@ namespace Microsoft.PowerFx
/// <returns></returns>
public T GetService<T>()
{
return (T)_services.GetService(typeof(T));
return (T)_services.GetService(typeof(T));
}
public bool TryGetService<T>(out T result)
@ -171,7 +171,7 @@ namespace Microsoft.PowerFx
}
// This may happen if the runtime symbols are missing a value and we failed to update.
}
}
}
// Fail?
@ -262,7 +262,7 @@ namespace Microsoft.PowerFx
result = await customTexlFunc.InvokeAsync(FunctionServices, args, _cancellationToken);
}
else
{
{
if (FunctionImplementations.TryGetValue(func, out var ptr))
{
try
@ -530,13 +530,13 @@ namespace Microsoft.PowerFx
}
return new InMemoryTableValue(node.IRContext, resultRows);
}
}
else if (node.Op == UnaryOpKind.RecordToRecord)
{
var fields = new List<NamedValue>();
var scopeContext = context.SymbolContext.WithScope(node.Scope);
var newScope = scopeContext.WithScopeValues((RecordValue)arg1);
foreach (var coercion in node.FieldCoercions)
{
CheckCancel();
@ -660,7 +660,7 @@ namespace Microsoft.PowerFx
private FormulaValue GetVariableOrFail(ResolvedObjectNode node, ISymbolSlot slot)
{
if (_symbolValues != null)
if (_symbolValues != null)
{
var value = _symbolValues.Get(slot);
if (value != null)
@ -670,7 +670,7 @@ namespace Microsoft.PowerFx
}
return ResolvedObjectHelpers.ResolvedObjectError(node);
}
}
public DateTime GetNormalizedDateTime(FormulaValue arg)
{

Просмотреть файл

@ -2,6 +2,8 @@
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.PowerFx.Core.Functions;
namespace Microsoft.PowerFx.Functions
{

Просмотреть файл

@ -6,14 +6,12 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.IR;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Interpreter;
using Microsoft.PowerFx.Types;
namespace Microsoft.PowerFx.Functions
@ -43,7 +41,7 @@ namespace Microsoft.PowerFx.Functions
public static IEnumerable<TexlFunction> FunctionList => FunctionImplementations.Keys;
public static readonly IReadOnlyDictionary<TexlFunction, AsyncFunctionPtr> FunctionImplementations;
public static readonly IReadOnlyDictionary<TexlFunction, AsyncFunctionPtr> FunctionImplementations;
public static FormattingInfo CreateFormattingInfo(EvalVisitor runner)
{

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -200,9 +199,8 @@ namespace Microsoft.PowerFx
var check = new CheckWrapper(this, definition.Body, record, definition.IsImperative);
var func = new UserDefinedTexlFunction(definition.Name, definition.ReturnType, definition.Parameters, check);
var exists = _symbolTable.Functions.Any(x => x.Name == definition.Name);
if (exists)
if (_symbolTable.Functions.AnyWithName(definition.Name))
{
throw new InvalidOperationException($"Function {definition.Name} is already defined");
}

Просмотреть файл

@ -32,7 +32,7 @@ namespace Microsoft.PowerFx.Core.Tests
config.AddFunction(func);
// Includes default functions
var functions = config.FunctionInfos.ToArray();
var functions = config.FunctionInfos.ToArray(); // Obsolete API
Assert.True(functions.Length > 100);
Assert.Contains(functions, x => x.Name == func.Name);

Просмотреть файл

@ -1,13 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerFx.Core.Public;
using System.Numerics;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Syntax;
using Xunit;
namespace Microsoft.PowerFx.Core.Tests
@ -18,8 +20,7 @@ namespace Microsoft.PowerFx.Core.Tests
public void TestAllBuiltinFunctionsHaveParameterDescriptions()
{
var texlFunctionsLibrary = BuiltinFunctionsCore.TestOnly_AllBuiltinFunctions;
var functions = texlFunctionsLibrary
.Where(x => !x.FunctionCategoriesMask.HasFlag(FunctionCategories.REST));
var functions = texlFunctionsLibrary.Where(x => !x.FunctionCategoriesMask.HasFlag(FunctionCategories.REST));
foreach (var function in functions)
{
@ -30,11 +31,261 @@ namespace Microsoft.PowerFx.Core.Tests
foreach (var paramName in function.GetParamNames())
{
Assert.True(
function.TryGetParamDescription(paramName, out var descr),
"Missing parameter description. Please add the following to Resources.pares: " + "About" + function.LocaleInvariantName + "_" + paramName);
Assert.True(function.TryGetParamDescription(paramName, out var descr), "Missing parameter description. Please add the following to Resources.pares: " + "About" + function.LocaleInvariantName + "_" + paramName);
}
}
}
[Fact]
public void TextFunctionSet_Ctor()
{
var tfs = new TexlFunctionSet();
Assert.NotNull(tfs);
Assert.False(tfs.Any());
}
[Fact]
public void TextFunctionSet_Ctor_NullFunction()
{
Assert.Throws<ArgumentNullException>(() => new TexlFunctionSet((TexlFunction)null));
Assert.Throws<ArgumentNullException>(() => new TexlFunctionSet((IEnumerable<TexlFunctionSet>)null));
}
[Fact]
public void TextFunctionSet_Ctor_NullFunction2()
{
Assert.Throws<ArgumentNullException>(() => new TexlFunctionSet((IEnumerable<TexlFunction>)null));
}
[Fact]
[Obsolete("Contains testing Obsolete functions")]
public void TextFunctionSet_OneFunc()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1");
Assert.Throws<ArgumentNullException>(() => tfs.Add((TexlFunction)null));
Assert.Throws<ArgumentNullException>(() => tfs.Add((TexlFunctionSet)null));
Assert.Throws<ArgumentNullException>(() => tfs.Add((IEnumerable<TexlFunction>)null));
tfs.Add(func1);
Assert.Empty(tfs.Enums);
Assert.Single(tfs.Functions);
Assert.Contains(tfs.Functions, f => f == func1);
Assert.Contains(tfs.WithName("func1"), f => f == func1);
Assert.Contains(tfs.WithInvariantName("func1"), f => f == func1);
Assert.Contains(tfs.WithInvariantName("func1", DPath.Root), f => f == func1);
Assert.Empty(tfs.WithInvariantName("func1", DPath.Root.Append(new DName("other"))));
Assert.Empty(tfs.WithName("FUNC1"));
Assert.Contains(tfs.WithInvariantName("FUNC1"), f => f == func1);
Assert.True(tfs.AnyWithName("func1"));
Assert.False(tfs.AnyWithName("FUNC1"));
Assert.Equal(1, tfs.Count());
Assert.Single(tfs.FunctionNames);
Assert.Contains(tfs.FunctionNames, f => f == "func1");
Assert.Single(tfs.InvariantFunctionNames);
Assert.Contains(tfs.InvariantFunctionNames, f => f == "func1");
}
[Fact]
[Obsolete("Contains testing Obsolete functions")]
public void TextFunctionSet_TwoFunc()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1");
var func2 = new TestTexlFunction("func2");
tfs.Add(func1);
tfs.Add(func2);
Assert.Empty(tfs.Enums);
Assert.Equal(2, tfs.Functions.Count());
Assert.Contains(tfs.Functions, f => f == func1);
Assert.Contains(tfs.Functions, f => f == func2);
Assert.Contains(tfs.WithName("func1"), f => f == func1);
Assert.Contains(tfs.WithName("func2"), f => f == func2);
Assert.Contains(tfs.WithInvariantName("func1"), f => f == func1);
Assert.Contains(tfs.WithInvariantName("func1", DPath.Root), f => f == func1);
Assert.Contains(tfs.WithInvariantName("func2"), f => f == func2);
Assert.Contains(tfs.WithInvariantName("func2", DPath.Root), f => f == func2);
Assert.Empty(tfs.WithName("FUNC1"));
Assert.Empty(tfs.WithName("FUNC2"));
Assert.Contains(tfs.WithInvariantName("FUNC1"), f => f == func1);
Assert.Contains(tfs.WithInvariantName("FUNC2"), f => f == func2);
Assert.True(tfs.AnyWithName("func1"));
Assert.False(tfs.AnyWithName("FUNC1"));
Assert.True(tfs.AnyWithName("func2"));
Assert.False(tfs.AnyWithName("FUNC2"));
Assert.Equal(2, tfs.Count());
Assert.Equal(2, tfs.FunctionNames.Count());
Assert.Equal(2, tfs.InvariantFunctionNames.Count());
Assert.Contains(tfs.FunctionNames, f => f == "func1");
Assert.Contains(tfs.FunctionNames, f => f == "func2");
Assert.Contains(tfs.InvariantFunctionNames, f => f == "func1");
Assert.Contains(tfs.InvariantFunctionNames, f => f == "func2");
Assert.Throws<ArgumentException>(() => tfs.Add(func1));
}
[Fact]
[Obsolete("Contains testing Obsolete functions")]
public void TextFunctionSet_TwoOverloads()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1");
var func2 = new TestTexlFunction("func1", DType.Number);
tfs.Add(func1);
tfs.Add(func2);
Assert.Empty(tfs.Enums);
Assert.Equal(2, tfs.Functions.Count());
Assert.Contains(tfs.Functions, f => f == func1);
Assert.Contains(tfs.Functions, f => f == func2);
Assert.Contains(tfs.WithName("func1"), f => f == func1);
Assert.Contains(tfs.WithInvariantName("func1"), f => f == func1);
Assert.Empty(tfs.WithName("FUNC1"));
Assert.Contains(tfs.WithInvariantName("FUNC1"), f => f == func1);
Assert.True(tfs.AnyWithName("func1"));
Assert.False(tfs.AnyWithName("FUNC1"));
Assert.Equal(2, tfs.Count());
Assert.Single(tfs.FunctionNames);
Assert.Single(tfs.InvariantFunctionNames);
Assert.Contains(tfs.FunctionNames, f => f == "func1");
Assert.Contains(tfs.InvariantFunctionNames, f => f == "func1");
}
[Fact]
public void TextFunctionSet_WithEnums()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1", requiredEnums: 1);
var func2 = new TestTexlFunction("func1", DType.Number, requiredEnums: 2);
tfs.Add(func1);
Assert.Single(tfs.Enums);
tfs.Add(func2);
Assert.Equal(3, tfs.Enums.Count());
Assert.Equal(2, tfs.Enums.Distinct().Count());
}
[Fact]
[Obsolete("Contains testing Obsolete functions")]
public void TextFunctionSet_Remove()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1", requiredEnums: 1);
tfs.Add(func1);
tfs.RemoveAll("func1");
Assert.Empty(tfs.Enums);
Assert.Empty(tfs.Namespaces);
Assert.Empty(tfs.Functions);
Assert.Empty(tfs.FunctionNames);
Assert.Empty(tfs.InvariantFunctionNames);
Assert.Empty(tfs.WithName("func1"));
Assert.Empty(tfs.WithInvariantName("func1"));
Assert.Empty(tfs.WithNamespace(DPath.Root));
tfs.Add(func1);
tfs.RemoveAll(func1);
Assert.Empty(tfs.Enums);
Assert.Empty(tfs.Namespaces);
Assert.Empty(tfs.Functions);
Assert.Empty(tfs.FunctionNames);
Assert.Empty(tfs.InvariantFunctionNames);
Assert.Empty(tfs.WithName("func1"));
Assert.Empty(tfs.WithInvariantName("func1"));
Assert.Empty(tfs.WithNamespace(DPath.Root));
}
[Fact]
[Obsolete("Contains testing Obsolete functions")]
public void TextFunctionSet_Remove2()
{
var tfs = new TexlFunctionSet();
var func1 = new TestTexlFunction("func1", requiredEnums: 1);
var func2 = new TestTexlFunction("func1", DType.Number, requiredEnums: 3);
tfs.Add(func1);
tfs.Add(func2);
Assert.Equal("Enum0, Enum0, Enum1, Enum2", string.Join(", ", tfs.Enums.OrderBy(x => x)));
Assert.Equal(2, tfs.Functions.Count());
Assert.Contains(tfs.Functions, f => f == func1);
Assert.Contains(tfs.Functions, f => f == func2);
Assert.Single(tfs.FunctionNames);
Assert.Single(tfs.InvariantFunctionNames);
Assert.Contains(tfs.FunctionNames, f => f == "func1");
Assert.Contains(tfs.InvariantFunctionNames, f => f == "func1");
tfs.RemoveAll("func1");
Assert.Empty(tfs.Enums);
Assert.Empty(tfs.Namespaces);
Assert.Empty(tfs.Functions);
Assert.Empty(tfs.FunctionNames);
Assert.Empty(tfs.InvariantFunctionNames);
Assert.Empty(tfs.WithName("func1"));
Assert.Empty(tfs.WithInvariantName("func1"));
Assert.Empty(tfs.WithNamespace(DPath.Root));
tfs.Add(func1);
tfs.Add(func2);
tfs.RemoveAll(func1);
Assert.Equal("Enum0, Enum1, Enum2", string.Join(", ", tfs.Enums.OrderBy(x => x)));
Assert.Single(tfs.Namespaces); // DPath.Root
Assert.Single(tfs.Functions);
Assert.Single(tfs.FunctionNames);
Assert.Single(tfs.InvariantFunctionNames);
Assert.Single(tfs.WithName("func1"));
Assert.Single(tfs.WithInvariantName("func1"));
Assert.Single(tfs.WithNamespace(DPath.Root));
tfs.RemoveAll(func2);
Assert.Empty(tfs.Enums);
Assert.Empty(tfs.Namespaces);
Assert.Empty(tfs.Functions);
Assert.Empty(tfs.FunctionNames);
Assert.Empty(tfs.InvariantFunctionNames);
Assert.Empty(tfs.WithName("func1"));
Assert.Empty(tfs.WithInvariantName("func1"));
Assert.Empty(tfs.WithNamespace(DPath.Root));
}
private class TestTexlFunction : TexlFunction
{
private readonly int _requiredEnums = 0;
public TestTexlFunction(string name, DType type = null, int requiredEnums = 0, DPath? path = null)
: this(path ?? DPath.Root, name, name, (string locale) => name, FunctionCategories.Text, type ?? DType.String, 0, 1, 1, type ?? DType.String)
{
_requiredEnums = requiredEnums;
}
public TestTexlFunction(DPath theNamespace, string name, string localeSpecificName, TexlStrings.StringGetter description, FunctionCategories functionCategories, DType returnType, BigInteger maskLambdas, int arityMin, int arityMax, params DType[] paramTypes)
: base(theNamespace, name, localeSpecificName, description, functionCategories, returnType, maskLambdas, arityMin, arityMax, paramTypes)
{
}
public override bool IsSelfContained => true;
public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
throw new NotImplementedException();
}
public override IEnumerable<string> GetRequiredEnumNames()
{
return _requiredEnums == 0
? Enumerable.Empty<string>()
: Enumerable.Range(0, _requiredEnums).Select(n => $"Enum{n}");
}
}
}
}

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.PowerFx.Core;
@ -18,7 +17,7 @@ using Xunit;
namespace Microsoft.PowerFx.Tests.IntellisenseTests
{
public class SuggestTests : IntellisenseTestBase
{
{
/// <summary>
/// This method does the same as <see cref="Suggest"/>, but filters the suggestions by their text so
/// that they can be more easily compared.
@ -62,10 +61,10 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
internal static PowerFxConfig Default_DisableRowScopeDisambiguationSyntax => PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder().WithDefaultEnums(), Features.DisableRowScopeDisambiguationSyntax);
// No enums, no functions. Adding functions will add back in associated enums, so to be truly empty, ensure no functions.
private PowerFxConfig EmptyEverything => PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder(), new TexlFunction[0]);
private PowerFxConfig EmptyEverything => PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder(), new TexlFunctionSet());
// No extra enums, but standard functions (which will include some enums).
private PowerFxConfig MinimalEnums => PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder().WithRequiredEnums(BuiltinFunctionsCore.BuiltinFunctionsLibrary));
private PowerFxConfig MinimalEnums => PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder().WithRequiredEnums(BuiltinFunctionsCore._library));
/// <summary>
/// Compares expected suggestions with suggestions made by PFx Intellisense for a given
@ -196,9 +195,7 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var config = Default;
var actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -219,9 +216,7 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var config = EmptyEverything;
var actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -237,9 +232,7 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var config = MinimalEnums;
var actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -299,8 +292,6 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var actualSuggestions = SuggestStrings(expression, Default, context);
Assert.True(actualSuggestions.Length > 0);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config);
Assert.True(actualSuggestions.Length > 0);
}
@ -324,8 +315,6 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var actualSuggestions = SuggestStrings(expression, config, context);
Assert.Equal(expectedSuggestions, actualSuggestions);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config, context);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -341,8 +330,6 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var actualSuggestions = SuggestStrings(expression, config, context);
Assert.Equal(expectedSuggestions, actualSuggestions);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config, context);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -361,15 +348,13 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
var config = PowerFxConfig.BuildWithEnumStore(
null,
new EnumStoreBuilder(),
new TexlFunction[] { BuiltinFunctionsCore.EndsWith, BuiltinFunctionsCore.Filter, BuiltinFunctionsCore.Table });
new TexlFunctionSet(new[] { BuiltinFunctionsCore.EndsWith, BuiltinFunctionsCore.Filter, BuiltinFunctionsCore.Table }));
var actualSuggestions = SuggestStrings(expression, config, lazyInstance);
Assert.Equal(expectedSuggestions, actualSuggestions);
// Intellisense requires iterating the field names for some operations
Assert.Equal(requiresExpansion, lazyInstance.EnumerableIterated);
// With adjusted config
AdjustConfig(config);
actualSuggestions = SuggestStrings(expression, config, lazyInstance);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
@ -484,7 +469,7 @@ namespace Microsoft.PowerFx.Tests.IntellisenseTests
public override int GetHashCode()
{
return 1;
}
}
}
}
}

Просмотреть файл

@ -4,8 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;
using Xunit;
@ -122,12 +122,12 @@ namespace Microsoft.PowerFx.Core.Tests
s1.RemoveVariable("x");
s1.RemoveVariable("x"); // Ok to remove if missing.
s1.AddVariable("x", FormulaType.String);
var result = _engine.Check("x", symbolTable: s1);
Assert.Equal(FormulaType.String, result.ReturnType);
// But can shadow.
var s2 = new SymbolTable();
var s2 = new SymbolTable();
var s21 = ReadOnlySymbolTable.Compose(s2, s1);
s2.AddVariable("x", FormulaType.Boolean); // hides s1.
@ -149,21 +149,25 @@ namespace Microsoft.PowerFx.Core.Tests
var s12 = ReadOnlySymbolTable.Compose(s1, s2);
Assert.Empty(s12.Functions);
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Empty(s12.Functions.Functions);
s2.AddFunction(func2);
var funcs = s12.Functions.ToArray();
var funcs = s12.Functions.Functions.ToArray();
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Single(funcs);
Assert.Same(func2, funcs[0]);
// Superceded
s1.AddFunction(func1);
funcs = s12.Functions.ToArray(); // Query again
#pragma warning disable CS0618 // Type or member is obsolete
funcs = s12.Functions.Functions.ToArray(); // Query again
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(2, funcs.Length); // both even though they have same name
// Enumerable is ordered. Takes s1 since that's higher precedence.
Assert.Same(func1, funcs[0]);
// Returns all combined.
INameResolver nr = s12;
var list = nr.LookupFunctions(func1.Namespace, func1.Name).ToArray();
@ -206,19 +210,21 @@ namespace Microsoft.PowerFx.Core.Tests
Assert.NotEqual(copyCount1, symbolTableCopy1.Functions.Count());
Assert.NotEqual(copyCount2, symbolTableCopy2.Functions.Count());
Assert.Contains(symbolTableOriginal.Functions, f => f.Name == "Abs");
Assert.Contains(symbolTableOriginal.Functions, f => f.Name == "Day");
Assert.Contains(symbolTableOriginal.Functions, f => f.Name == "Text");
Assert.Contains(symbolTableOriginal.Functions, f => f.Name == "Value");
Assert.Contains(symbolTableCopy1.Functions, f => f.Name == "Day");
Assert.Contains(symbolTableCopy1.Functions, f => f.Name == "Text");
Assert.Contains(symbolTableCopy1.Functions, f => f.Name == "Value");
Assert.Contains(symbolTableCopy2.Functions, f => f.Name == "Abs");
Assert.Contains(symbolTableCopy2.Functions, f => f.Name == "Text");
Assert.Contains(symbolTableCopy2.Functions, f => f.Name == "Value");
Assert.True(symbolTableOriginal.Functions.AnyWithName("Abs"));
Assert.True(symbolTableOriginal.Functions.AnyWithName("Day"));
Assert.True(symbolTableOriginal.Functions.AnyWithName("Text"));
Assert.True(symbolTableOriginal.Functions.AnyWithName("Value"));
Assert.DoesNotContain(symbolTableCopy1.Functions, f => f.Name == "Abs");
Assert.DoesNotContain(symbolTableCopy2.Functions, f => f.Name == "Day");
Assert.True(symbolTableCopy1.Functions.AnyWithName("Day"));
Assert.True(symbolTableCopy1.Functions.AnyWithName("Text"));
Assert.True(symbolTableCopy1.Functions.AnyWithName("Value"));
Assert.True(symbolTableCopy2.Functions.AnyWithName("Abs"));
Assert.True(symbolTableCopy2.Functions.AnyWithName("Text"));
Assert.True(symbolTableCopy2.Functions.AnyWithName("Value"));
Assert.False(symbolTableCopy1.Functions.AnyWithName("Abs"));
Assert.False(symbolTableCopy2.Functions.AnyWithName("Day"));
// Check if nothing else has been copied
Assert.Empty(symbolTableCopy1.SymbolNames);
@ -260,5 +266,31 @@ namespace Microsoft.PowerFx.Core.Tests
Assert.Equal(0, callbackCount);
}
}
[Fact]
public void ComposedReadOnlySymbolTableFunctionCacheTest()
{
var symbolTable = new SymbolTable();
symbolTable.AddFunction(new BlankFunction());
var composed = new ComposedReadOnlySymbolTable(symbolTable);
var func1 = composed.Functions;
Assert.NotNull(func1);
Assert.Equal(1, func1.Count());
var func2 = composed.Functions;
Assert.NotNull(func2);
Assert.Equal(1, func2.Count());
Assert.Same(func1, func2);
symbolTable.AddFunction(new SqrtFunction());
var func3 = composed.Functions;
Assert.NotNull(func3);
Assert.Equal(2, func3.Count());
}
}
}

Просмотреть файл

@ -32,6 +32,7 @@ namespace Microsoft.PowerFx.Core.Tests
"DType._kindToSuperkindMapping",
"DTypeSpecParser._types",
"BuiltinFunctionsCore._library",
"BuiltinFunctionsCore._testOnlyLibrary",
"BuiltinFunctionsCore._featureGateFunctions",
"ArgumentSuggestions._languageCodeSuggestions",
"IntellisenseProvider.SuggestionHandlers",

Просмотреть файл

@ -74,10 +74,14 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enumeration
#pragma warning disable CS0618 // Type or member is obsolete
var func = engine.GetAllFunctionNames().First(name => name == "CustomFunctionError");
#pragma warning restore CS0618 // Type or member is obsolete
Assert.NotNull(func);
#pragma warning disable CS0618 // Type or member is obsolete
var func2 = engine.GetAllFunctionNames().First(name => name == "CustomFunctionError2");
#pragma warning restore CS0618 // Type or member is obsolete
Assert.NotNull(func2);
// Test for non async invokes.
@ -124,7 +128,9 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enumeration
#pragma warning disable CS0618 // Type or member is obsolete
var func = engine.GetAllFunctionNames().First(name => name == "NullFunction");
#pragma warning restore CS0618 // Type or member is obsolete
Assert.NotNull(func);
// Can be invoked.
@ -140,8 +146,8 @@ namespace Microsoft.PowerFx.Tests
config.AddFunction(new TestCustomFunction());
var engine = new RecalcEngine(config);
// Shows up in enuemeration
var func = engine.GetAllFunctionNames().First(name => name == "TestCustom");
// Shows up in enumeration
var func = engine.GetFunctionsByName("TestCustom");
Assert.NotNull(func);
// Can be invoked.
@ -167,7 +173,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enumeration
var func = engine.GetAllFunctionNames().First(name => name == "TestCustom");
var func = engine.GetFunctionsByName("TestCustom");
Assert.NotNull(func);
// With error as arg.
@ -208,9 +214,9 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enuemeration
var func = engine.GetAllFunctionNames().First(name => name == "RecordTest");
var func = engine.GetFunctionsByName("RecordTest");
Assert.NotNull(func);
var invalidFunc = engine.GetAllFunctionNames().First(name => name == "InvalidRecordTest");
var invalidFunc = engine.GetFunctionsByName("InvalidRecordTest");
Assert.NotNull(invalidFunc);
// Can be invoked.
@ -303,7 +309,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enuemeration
var func = engine.GetAllFunctionNames().First(name => name == "TestCallback");
var func = engine.GetFunctionsByName("TestCallback");
Assert.NotNull(func);
var result = engine.Eval("TestCallback(1=2)");
@ -329,7 +335,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enuemeration
var func = engine.GetAllFunctionNames().First(name => name == "Wait");
var func = engine.GetFunctionsByName("Wait");
Assert.NotNull(func);
// Can be invoked.
@ -401,7 +407,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enuemeration
var func = engine.GetAllFunctionNames().First(name => name == "MockAnd2Arg");
var func = engine.GetFunctionsByName("MockAnd2Arg");
Assert.NotNull(func);
// Can be invoked.
@ -438,7 +444,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enumeration
var func = engine.GetAllFunctionNames().First(name => name == "TestCustomAsync");
var func = engine.GetFunctionsByName("TestCustomAsync");
Assert.NotNull(func);
// Can be invoked.
@ -586,7 +592,7 @@ namespace Microsoft.PowerFx.Tests
var engine = new RecalcEngine(config);
// Shows up in enumeration
var func = engine.GetAllFunctionNames().First(name => name == "CustomAsync");
var func = engine.GetFunctionsByName("CustomAsync");
Assert.NotNull(func);
// Can be invoked.
@ -743,8 +749,8 @@ namespace Microsoft.PowerFx.Tests
config.AddFunction(new SetFieldStrFunction());
var engine = new RecalcEngine(config);
var count = engine.GetAllFunctionNames().Count(name => name == "SetField");
Assert.Equal(1, count); // no duplicates
var setFieldFunctions = engine.GetFunctionsByName("SetField");
Assert.Equal(2, setFieldFunctions.Count());
// Duplicates?
var result = engine.Eval(expr);

Просмотреть файл

@ -6,8 +6,8 @@ using System.Linq;
using System.Reflection;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Tests;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Types;
using Xunit;
using static Microsoft.PowerFx.Functions.Library;
@ -18,7 +18,7 @@ namespace Microsoft.PowerFx.Tests
[Fact]
public void TabularOverloadListIsOverloadOfSingleFunction()
{
var type = typeof(Microsoft.PowerFx.Functions.Library);
var type = typeof(Functions.Library);
var simpleFunctions = type.GetProperty("SimpleFunctionImplementations", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null)
as IReadOnlyDictionary<TexlFunction, AsyncFunctionPtr>;
Assert.NotNull(simpleFunctions);
@ -33,6 +33,16 @@ namespace Microsoft.PowerFx.Tests
ValidateOverloads(simpleFunctions, tabularMultiArgsOverloads, isMultiArg: true);
}
[Fact]
public void ValidateNoMutation()
{
int libraryCount = BuiltinFunctionsCore.BuiltinFunctionsLibrary.Count();
int testOnlyCount = BuiltinFunctionsCore.TestOnly_AllBuiltinFunctions.Count();
Assert.Equal(libraryCount, BuiltinFunctionsCore.BuiltinFunctionsLibrary.ToList().Count());
Assert.True(testOnlyCount > libraryCount);
}
private void ValidateOverloads(IReadOnlyDictionary<TexlFunction, AsyncFunctionPtr> simpleFunctions, IReadOnlyDictionary<TexlFunction, AsyncFunctionPtr> tabularOverloads, bool isMultiArg)
{
foreach (var tabularOverload in tabularOverloads.Keys)

Просмотреть файл

@ -13,12 +13,11 @@ using Microsoft.PowerFx.Intellisense;
using Microsoft.PowerFx.Tests.IntellisenseTests;
using Microsoft.PowerFx.Types;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.PowerFx.Interpreter.Tests
{
public class InterpreterSuggestTests : IntellisenseTestBase
{
{
private string[] SuggestStrings(string expression, PowerFxConfig config, RecordType parameterType)
{
Assert.NotNull(expression);
@ -48,7 +47,7 @@ namespace Microsoft.PowerFx.Interpreter.Tests
[InlineData("TopOptionSetField <> |", "OptionSet", "OtherOptionSet")]
[InlineData("TopOptionSetField <> Opt|", "OptionSet", "TopOptionSetField", "OtherOptionSet")]
public void TestSuggestOptionSets(string expression, params string[] expectedSuggestions)
{
{
var config = PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder());
var optionSet = new OptionSet("OptionSet", DisplayNameUtility.MakeUnique(new Dictionary<string, string>()
@ -80,7 +79,7 @@ namespace Microsoft.PowerFx.Interpreter.Tests
var actualSuggestions = SuggestStrings(expression, engine, parameterType);
Assert.Equal(expectedSuggestions, actualSuggestions);
// Now try with Globals instead of RowScope
foreach (var field in parameterType.GetFieldTypes())
{
@ -96,7 +95,7 @@ namespace Microsoft.PowerFx.Interpreter.Tests
[InlineData("Dis|", "DisplayOpt", "DisplayRowScope")] // Match to row scope
public void TestSuggestOptionSetsDisplayName(string expression, params string[] expectedSuggestions)
{
var config = PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder(), new TexlFunction[0]);
var config = PowerFxConfig.BuildWithEnumStore(null, new EnumStoreBuilder(), new TexlFunctionSet());
var optionSet = new OptionSet("OptionSet", DisplayNameUtility.MakeUnique(new Dictionary<string, string>()
{

Просмотреть файл

@ -9,8 +9,10 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Tests;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Functions;
@ -250,7 +252,7 @@ namespace Microsoft.PowerFx.Tests
AssertUpdate("B-->2;");
// Can't set formulas, they're read only
var check = engine.Check("Set(B, 12)");
var check = engine.Check("Set(B, 12)");
Assert.False(check.IsSuccess);
// Set() function triggers recalc chain.
@ -471,26 +473,30 @@ namespace Microsoft.PowerFx.Tests
[Fact]
public void CheckFunctionCounts()
{
var engine1 = new Engine(new PowerFxConfig());
var config = new PowerFxConfig();
config.EnableParseJSONFunction();
var engine1 = new Engine(config);
// Pick a function in core but not implemented in interpreter.
var nyiFunc = BuiltinFunctionsCore.ISOWeekNum;
Assert.Contains(nyiFunc, engine1.Functions);
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(nyiFunc, engine1.Functions.Functions);
#pragma warning restore CS0618 // Type or member is obsolete
// RecalcEngine will add the interpreter's functions.
var engine2 = new RecalcEngine();
var engine2 = new RecalcEngine(config);
Assert.DoesNotContain(nyiFunc, engine2.Functions);
#pragma warning disable CS0618 // Type or member is obsolete
Assert.DoesNotContain(nyiFunc, engine2.Functions.Functions);
#pragma warning restore CS0618 // Type or member is obsolete
var names = engine2.GetAllFunctionNames().ToArray();
Assert.True(names.Length > 100);
Assert.True(engine2.FunctionCount > 100);
// Spot check some known functions
Assert.Contains("Cos", names);
Assert.Contains("Filter", names);
Assert.Contains("Cos", names);
Assert.NotEmpty(engine2.Functions.WithName("Cos"));
Assert.NotEmpty(engine2.Functions.WithName("ParseJSON"));
}
[Fact]
@ -691,7 +697,9 @@ namespace Microsoft.PowerFx.Tests
};
var func = BuiltinFunctionsCore.AsType; // Function not already in engine
Assert.DoesNotContain(func, recalcEngine.Functions); // didn't get auto-added by engine.
#pragma warning disable CS0618 // Type or member is obsolete
Assert.DoesNotContain(func, recalcEngine.Functions.Functions); // didn't get auto-added by engine.
#pragma warning restore CS0618 // Type or member is obsolete
// We can mutate config after engine is created.
var optionSet = new OptionSet("foo", DisplayNameUtility.MakeUnique(new Dictionary<string, string>() { { "one key", "one value" } }));
@ -699,9 +707,13 @@ namespace Microsoft.PowerFx.Tests
config.SymbolTable.AddEntity(optionSet);
Assert.True(config.TryGetVariable(new DName("foo"), out _));
Assert.Contains(func, recalcEngine.Functions); // function was added to the config.
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(func, recalcEngine.Functions.Functions); // function was added to the config.
#pragma warning restore CS0618 // Type or member is obsolete
Assert.DoesNotContain(BuiltinFunctionsCore.Abs, recalcEngine.Functions);
#pragma warning disable CS0618 // Type or member is obsolete
Assert.DoesNotContain(BuiltinFunctionsCore.Abs, recalcEngine.Functions.Functions);
#pragma warning restore CS0618 // Type or member is obsolete
}
[Fact]
@ -713,6 +725,88 @@ namespace Microsoft.PowerFx.Tests
Assert.Throws<ArgumentException>(() => config.AddFunction(BuiltinFunctionsCore.Blank));
}
[Fact]
public void RecalcEngine_FunctionOrdering1()
{
var config = new PowerFxConfig(new CultureInfo("en-US"), Features.All);
config.AddFunction(new TestFunctionMultiply());
config.AddFunction(new TestFunctionSubstract());
var engine = new RecalcEngine(config);
var result = engine.Eval("Func(7, 11)");
Assert.IsType<NumberValue>(result);
// Multiply function is first and a valid overload so that's the one we use as coercion is valid for this one
Assert.Equal(77.0, (result as NumberValue).Value);
}
[Fact]
public void RecalcEngine_FunctionOrdering2()
{
var config = new PowerFxConfig(new CultureInfo("en-US"), Features.All);
config.AddFunction(new TestFunctionSubstract());
config.AddFunction(new TestFunctionMultiply());
var engine = new RecalcEngine(config);
var result = engine.Eval("Func(7, 11)");
Assert.IsType<NumberValue>(result);
// Substract function is first and a valid overload so that's the one we use as coercion is valid for this one
Assert.Equal(-4.0, (result as NumberValue).Value);
}
private class TestFunctionMultiply : CustomTexlFunction
{
public override bool IsSelfContained => true;
public override bool SupportsParamCoercion => true;
public TestFunctionMultiply()
: base("Func", DType.Number, DType.Number, DType.String)
{
}
public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
yield return new[] { TexlStrings.IsBlankArg1 };
}
public override Task<FormulaValue> InvokeAsync(IServiceProvider serviceProvider, FormulaValue[] args, CancellationToken cancellationToken)
{
var arg0 = args[0] as NumberValue;
var arg1 = args[1] as StringValue;
return Task.FromResult<FormulaValue>(NumberValue.New(arg0.Value * double.Parse(arg1.Value)));
}
}
private class TestFunctionSubstract : CustomTexlFunction
{
public override bool IsSelfContained => true;
public override bool SupportsParamCoercion => true;
public TestFunctionSubstract()
: base("Func", DType.Number, DType.String, DType.Number)
{
}
public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
yield return new[] { TexlStrings.IsBlankArg1 };
}
public override Task<FormulaValue> InvokeAsync(IServiceProvider serviceProvider, FormulaValue[] args, CancellationToken cancellationToken)
{
var arg0 = args[0] as StringValue;
var arg1 = args[1] as NumberValue;
return Task.FromResult<FormulaValue>(NumberValue.New(double.Parse(arg0.Value) - arg1.Value));
}
}
[Fact]
public void OptionSetChecks()
{
@ -1013,7 +1107,7 @@ namespace Microsoft.PowerFx.Tests
var recordType = RecordType.Empty()
.Add("x", FormulaType.Number)
.Add("y", FormulaType.Number);
var result = engine.Check("x+y", recordType);
var eval = result.GetEvaluator();

Просмотреть файл

@ -72,7 +72,7 @@ namespace Microsoft.PowerFx.Tests
// Pick a "small" memory size that's large enough to execute basic expressions but will
// fail on intentionally large expressions.
private const int DefaultMemorySizeBytes = 50 * 1000;
private const int DefaultMemorySizeBytes = 100 * 1024;
// Verify memory limits.
[Theory]