зеркало из https://github.com/microsoft/Power-Fx.git
Optimize function lookup (#1019)
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:
Родитель
83e3f81772
Коммит
341a621f3b
|
@ -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]
|
||||
|
|
Загрузка…
Ссылка в новой задаче