зеркало из https://github.com/microsoft/Power-Fx.git
UO.TryGetProperty should determine the result value (#2592)
Issue https://github.com/microsoft/Power-Fx/issues/2591.
This commit is contained in:
Родитель
8c5342c598
Коммит
72f09636da
|
@ -101,6 +101,31 @@ namespace Microsoft.PowerFx.Types
|
|||
|
||||
public abstract bool TryGetProperty(string value, out IUntypedObject result);
|
||||
|
||||
/// <summary>
|
||||
/// Get the property value of the untyped object.
|
||||
/// Hosts should override this method in case a different return value is needed. For example, a host may want to return a ErrorValue in case of a missing property.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="returnType"></param>
|
||||
/// <param name="span"></param>
|
||||
/// <returns></returns>
|
||||
public virtual FormulaValue GetProperty(string value, FormulaType returnType)
|
||||
{
|
||||
if (TryGetProperty(value, out var res))
|
||||
{
|
||||
if (res.Type == FormulaType.Blank)
|
||||
{
|
||||
return new BlankValue(IRContext.NotInSource(returnType));
|
||||
}
|
||||
|
||||
return new UntypedObjectValue(IRContext.NotInSource(returnType), res);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BlankValue(IRContext.NotInSource(returnType));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool TryGetPropertyNames(out IEnumerable<string> propertyNames);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -558,7 +558,12 @@ namespace Microsoft.PowerFx
|
|||
if (arg1 is UntypedObjectValue cov && arg2 is StringValue sv)
|
||||
{
|
||||
if (cov.Impl.Type is ExternalType et && (et.Kind == ExternalTypeKind.Object || et.Kind == ExternalTypeKind.ArrayAndObject))
|
||||
{
|
||||
{
|
||||
if (cov.Impl is UntypedObjectBase untypedObjectBase)
|
||||
{
|
||||
return untypedObjectBase.GetProperty(sv.Value, node.IRContext.ResultType);
|
||||
}
|
||||
|
||||
if (cov.Impl.TryGetProperty(sv.Value, out var res))
|
||||
{
|
||||
if (res.Type == FormulaType.Blank)
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Data;
|
||||
using System.Linq;
|
||||
using Microsoft.PowerFx.Core.IR;
|
||||
using Microsoft.PowerFx.Syntax;
|
||||
using Microsoft.PowerFx.Types;
|
||||
using Xunit;
|
||||
|
||||
|
@ -138,6 +139,30 @@ namespace Microsoft.PowerFx.Interpreter.Tests
|
|||
Assert.Equal(97m, result.ToObject());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PadUntypedObjectMissingProperty()
|
||||
{
|
||||
var uo1 = new PadUntypedObject(GetDataTable());
|
||||
var uo2 = new PadUntypedObject2(GetDataTable());
|
||||
|
||||
var uov1 = new UntypedObjectValue(IRContext.NotInSource(FormulaType.UntypedObject), uo1);
|
||||
var uov2 = new UntypedObjectValue(IRContext.NotInSource(FormulaType.UntypedObject), uo2);
|
||||
|
||||
RecalcEngine engine = new RecalcEngine();
|
||||
|
||||
engine.Config.SymbolTable.EnableMutationFunctions();
|
||||
engine.UpdateVariable("padTable1", uov1);
|
||||
engine.UpdateVariable("padTable2", uov2);
|
||||
|
||||
// PadUntypedObject does not override GetProperty. Returns blank if property is missing.
|
||||
var result1 = engine.Eval(@"Index(padTable1, 1).Missing");
|
||||
Assert.IsType<BlankValue>(result1);
|
||||
|
||||
// PadUntypedObject2 overrides GetProperty. Returns error if property is missing.
|
||||
var result2 = engine.Eval(@"Index(padTable2, 1).Missing");
|
||||
Assert.IsType<ErrorValue>(result2);
|
||||
}
|
||||
|
||||
private DataTable GetDataTable()
|
||||
{
|
||||
var dt = new DataTable("someTable");
|
||||
|
@ -562,6 +587,11 @@ namespace Microsoft.PowerFx.Interpreter.Tests
|
|||
|
||||
throw new CustomFunctionErrorException("Something went wrong.", ErrorKind.InvalidArgument);
|
||||
}
|
||||
|
||||
public override FormulaValue GetProperty(string value, FormulaType returnType)
|
||||
{
|
||||
return new ErrorValue(IRContext.NotInSource(returnType), new ExpressionError() { Kind = ErrorKind.InvalidArgument });
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче