Change Lookup order in BinderUtils.TryGetConstantValue to check entitystore first (#2703)

NameResolver.Lookup is a weirdly expensive operation when done from the
middle of a running analysis pass.
A few functions call TryGetConstantValue from CheckTypes, which is
called during analysis to get functions result types.
In JSON it was possible to move that to CheckSemantics, but in Match, we
want to avoid the expensive call to Lookup if we can, so we first look
in the EntityStore to resolve enums.

This doesn't meaningfully change the scenario for non PA hosts, as the
entity store is a PA-only concept.
This commit is contained in:
McCall Saltzman 2024-10-21 16:09:24 -07:00 коммит произвёл GitHub
Родитель c2297b1aed
Коммит 37533140c9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 14 добавлений и 19 удалений

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

@ -1563,18 +1563,9 @@ namespace Microsoft.PowerFx.Core.Binding
// Possibly an enumeration
var dottedNameNode = node.AsDottedName();
if (dottedNameNode.Left.Kind == NodeKind.FirstName)
{
// Strongly-typed enums
if (context.NameResolver.Lookup(dottedNameNode.Left.AsFirstName().Ident.Name, out NameLookupInfo nameInfo) && nameInfo.Kind == BindKind.Enum)
{
if (nameInfo.Data is EnumSymbol enumSymbol && enumSymbol.TryGetValue(dottedNameNode.Right.Name, out OptionSetValue osv))
{
nodeValue = osv.ToObject().ToString();
return true;
}
}
// With strongly-typed enums disabled
{
// If the entity scope exists, look up from there.
// Once PA Client impls Strongly Typed enums, this may need to update.
DType enumType = DType.Invalid;
if (context.NameResolver.EntityScope?.TryGetNamedEnum(dottedNameNode.Left.AsFirstName().Ident.Name, out enumType) ?? false)
{
@ -1586,6 +1577,16 @@ namespace Microsoft.PowerFx.Core.Binding
return true;
}
}
}
// Strongly-typed enums
if (context.NameResolver.Lookup(dottedNameNode.Left.AsFirstName().Ident.Name, out NameLookupInfo nameInfo, NameLookupPreferences.GlobalsOnly) && nameInfo.Kind == BindKind.Enum)
{
if (nameInfo.Data is EnumSymbol enumSymbol && enumSymbol.TryGetValue(dottedNameNode.Right.Name, out OptionSetValue osv))
{
nodeValue = osv.ToObject().ToString();
return true;
}
}
}

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

@ -82,13 +82,6 @@ namespace Microsoft.PowerFx.Core.Texl.Builtins
{
return false;
}
TexlNode optionsNode = args[1];
if (!IsConstant(context, argTypes, optionsNode, out string nodeValue))
{
errors.EnsureError(optionsNode, TexlStrings.ErrFunctionArg2ParamMustBeConstant, "JSON", TexlStrings.JSONArg2.Invoke());
return false;
}
}
return true;
@ -123,6 +116,7 @@ namespace Microsoft.PowerFx.Core.Texl.Builtins
TexlNode optionsNode = args[1];
if (!IsConstant(binding.CheckTypesContext, argTypes, optionsNode, out string nodeValue))
{
errors.EnsureError(optionsNode, TexlStrings.ErrFunctionArg2ParamMustBeConstant, "JSON", TexlStrings.JSONArg2.Invoke());
return;
}