Skip to content

Commit

Permalink
Fixes. Rebuild Collect IR based on arguments.
Browse files Browse the repository at this point in the history
  • Loading branch information
anderson-joyle committed Mar 4, 2024
1 parent 0b94653 commit f79b5ab
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 56 deletions.
3 changes: 1 addition & 2 deletions src/libraries/Microsoft.PowerFx.Core/IR/CoercionKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ internal enum CoercionKind
CurrencyToText,
TextToCurrency,
CurrencyToBoolean,
BooleanToCurrency,
PrimitiveToSingleColumnRecord,
BooleanToCurrency,
}
}
7 changes: 0 additions & 7 deletions src/libraries/Microsoft.PowerFx.Core/IR/CoercionMatrix.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using Microsoft.PowerFx.Core.Entities;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;

Expand All @@ -22,12 +21,6 @@ public static CoercionKind GetCoercionKind(DType fromType, DType toType, bool us
if (fromType.IsAggregate && toType.Kind == DKind.DataEntity)
{
return CoercionKind.AggregateToDataEntity;
}

// Coercion from a primitive type to a single column record type.
if (fromType.IsPrimitive && toType.IsRecord)
{
return CoercionKind.PrimitiveToSingleColumnRecord;
}

if (toType.IsLargeImage && (fromType.Kind == DKind.Image || fromType == DType.MinimalLargeImage))
Expand Down
8 changes: 0 additions & 8 deletions src/libraries/Microsoft.PowerFx.Core/IR/IRTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.PowerFx.Core.App.ErrorContainers;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Errors;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.IR.Nodes;
using Microsoft.PowerFx.Core.IR.Symbols;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Texl;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Types;
Expand Down Expand Up @@ -1179,9 +1174,6 @@ private IntermediateNode InjectCoercion(IntermediateNode child, IRTranslatorCont
break;
case CoercionKind.PenImageToText:
unaryOpKind = UnaryOpKind.PenImageToText;
break;
case CoercionKind.PrimitiveToSingleColumnRecord:
unaryOpKind = UnaryOpKind.PrimitiveToSingleColumnRecord;
break;
case CoercionKind.UntypedToText:
return new CallNode(IRContext.NotInSource(FormulaType.Build(toType)), BuiltinFunctionsCore.Text_UO, child);
Expand Down
3 changes: 1 addition & 2 deletions src/libraries/Microsoft.PowerFx.Core/IR/Nodes/UnaryOpKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ internal enum UnaryOpKind
DateToDateTime,

BooleanToOptionSet,
AggregateToDataEntity,
PrimitiveToSingleColumnRecord,
AggregateToDataEntity,

// Argument pre-processesor in IR Phase.

Expand Down
61 changes: 47 additions & 14 deletions src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Collect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
using Microsoft.PowerFx.Core.Errors;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Functions.FunctionArgValidators;
using Microsoft.PowerFx.Core.IR;
using Microsoft.PowerFx.Core.IR.Nodes;
using Microsoft.PowerFx.Core.IR.Symbols;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Syntax;
using Microsoft.PowerFx.Syntax;
using Microsoft.PowerFx.Types;
using RecordNode = Microsoft.PowerFx.Core.IR.Nodes.RecordNode;

namespace Microsoft.PowerFx.Core.Texl.Builtins
{
Expand Down Expand Up @@ -91,7 +95,7 @@ protected CollectFunction(string name, TexlStrings.StringGetter description)
return base.GetSignatures(arity);
}

public virtual DType GetCollectedType(Features features, DType argType, TexlNode arg, ref Dictionary<TexlNode, DType> nodeToCoercedTypeMap)
public virtual DType GetCollectedType(PowerFx.Features features, DType argType)
{
Contracts.Assert(argType.IsValid);

Expand All @@ -114,7 +118,7 @@ public bool TryGetUnifiedCollectedTypeCanvas(TexlNode[] args, DType[] argTypes,

for (int i = 1; i < argc; i++)
{
DType argType = GetCollectedType(features, argTypes[i], args[i], ref nodeToCoercedTypeMap);
DType argType = GetCollectedType(features, argTypes[i]);

// The subsequent args should all be aggregates.
if (!argType.IsAggregate)
Expand Down Expand Up @@ -176,7 +180,7 @@ private bool TryGetUnifiedCollectedTypeV1(TexlNode[] args, DType[] argTypes, IEr

for (var i = 1; i < argc; i++)
{
DType argType = GetCollectedType(features, argTypes[i], args[i], ref nodeToCoercedTypeMap);
DType argType = GetCollectedType(features, argTypes[i]);

// !!! How is it possible for an argtype to be a primitive and an aggregate at the same time?
//if (argType.DisplayNameProvider == null && argType.Kind == DKind.ObjNull)
Expand Down Expand Up @@ -314,12 +318,14 @@ public override void CheckSemantics(TexlBinding binding, TexlNode[] args, DType[
}

base.CheckSemantics(binding, args, argTypes, errors);
base.ValidateArgumentIsMutable(binding, args[0], errors);
base.ValidateArgumentIsMutable(binding, args[0], errors);

int skip = 1;

MutationUtils.CheckSemantics(binding, this, args, argTypes, errors);
MutationUtils.CheckForReadOnlyFields(argTypes[0], args.Skip(skip).ToArray(), argTypes.Skip(skip).ToArray(), errors);
MutationUtils.CheckSemantics(binding, this, args, argTypes, errors);

if (binding.Features.PowerFxV1CompatibilityRules)
{
MutationUtils.CheckForReadOnlyFields(argTypes[0], args.Skip(1).ToArray(), argTypes.Skip(1).ToArray(), errors);
}
}

// This method returns true if there are special suggestions for a particular parameter of the function.
Expand All @@ -330,7 +336,7 @@ public override bool HasSuggestionsForParam(int argumentIndex)
return argumentIndex == 0;
}

public override bool TryGetDataSourceNodes(CallNode callNode, TexlBinding binding, out IList<FirstNameNode> dsNodes)
public override bool TryGetDataSourceNodes(PowerFx.Syntax.CallNode callNode, TexlBinding binding, out IList<FirstNameNode> dsNodes)
{
Contracts.AssertValue(callNode);
Contracts.AssertValue(binding);
Expand Down Expand Up @@ -373,7 +379,7 @@ public override IEnumerable<Identifier> GetIdentifierOfModifiedValue(TexlNode[]
return identifiers;
}

public override bool IsAsyncInvocation(CallNode callNode, TexlBinding binding)
public override bool IsAsyncInvocation(PowerFx.Syntax.CallNode callNode, TexlBinding binding)
{
Contracts.AssertValue(callNode);
Contracts.AssertValue(binding);
Expand All @@ -390,7 +396,7 @@ public static DType GetCollectedTypeForGivenArgType(Features features, DType arg
return argType;
}

CollectionUtils.Add(ref nodeToCoercedTypeMap, arg, singleColumnRecordType);
//CollectionUtils.Add(ref nodeToCoercedTypeMap, arg, singleColumnRecordType);

return singleColumnRecordType;
}
Expand Down Expand Up @@ -431,9 +437,36 @@ public static string GetInvariantNameForRecord(PowerFx.Features features, DKind
return CreateInvariantFieldName(features, dKind);
}

public override DType GetCollectedType(Features features, DType argType, TexlNode arg, ref Dictionary<TexlNode, DType> nodeToCoercedTypeMap)
public override DType GetCollectedType(Features features, DType argType)
{
return GetCollectedTypeForGivenArgType(features, argType, arg, ref nodeToCoercedTypeMap);
return GetCollectedTypeForGivenArgType(features, argType);
}

internal override IntermediateNode CreateIRCallNode(PowerFx.Syntax.CallNode node, IRTranslator.IRTranslatorContext context, List<IntermediateNode> args, ScopeSymbol scope)
{
var newArgs = new List<IntermediateNode>() { args[0] };

// !!! Blank()?

foreach (var arg in args.Skip(1))
{
if (arg.IRContext.ResultType._type.IsPrimitive)
{
newArgs.Add(
new RecordNode(
new IRContext(arg.IRContext.SourceContext, RecordType.Empty().Add(TableValue.ValueName, arg.IRContext.ResultType)),
new Dictionary<DName, IntermediateNode>
{
{ TableValue.ValueDName, arg }
}));
}
else
{
newArgs.Add(arg);
}
}

return base.CreateIRCallNode(node, context, newArgs, scope);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ internal async Task<FormulaValue> Process(IServiceProvider runtimeServiceProvide
else if (arg is ErrorValue)
{
return arg;
}

// !!! This should be moved to IR.
else if (arg is BlankValue)
{
if (tableValue.Type._type.IsSingleColumnTable && tableValue.Type.GetFieldTypes().First().Name.Value == "Value")
{
resultRows.Add(await tableValue.AppendAsync(CreateRecordFromPrimitive(tableValue, arg), cancellationToken).ConfigureAwait(false));
}
}

// !!! How to handle BlankValue?
//else if (arg is BlankValue && !tableValue.Type._type.IsSingleColumnTable)
//{
// continue;
//}
}

if (resultRows.Count == 0)
Expand All @@ -130,6 +133,11 @@ internal async Task<FormulaValue> Process(IServiceProvider runtimeServiceProvide
{
return CompileTimeTypeWrapperRecordValue.AdjustType(tableValue.Type.ToRecord(), (RecordValue)resultRows.First().ToFormulaValue());
}
}

private RecordValue CreateRecordFromPrimitive(TableValue tableValue, FormulaValue arg)
{
return FormulaValue.NewRecordFromFields(tableValue.Type.ToRecord(), new NamedValue("Value", arg));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -523,17 +523,6 @@ internal static partial class Library
checkRuntimeValues: DeferRuntimeValueChecking,
returnBehavior: ReturnBehavior.ReturnBlankIfAnyArgIsBlank,
targetFunction: UntypedStringToUntypedDecimal)
},
{
UnaryOpKind.PrimitiveToSingleColumnRecord,
StandardErrorHandling<FormulaValue>(
functionName: null, // internal function, no user-facing name
expandArguments: NoArgExpansion,
replaceBlankValues: DoNotReplaceBlank,
checkRuntimeTypes: ExactValueTypeOrBlank<FormulaValue>,
checkRuntimeValues: DeferRuntimeValueChecking,
returnBehavior: ReturnBehavior.AlwaysEvaluateAndReturnResult,
targetFunction: PrimitiveToSingleColumnRecord)
},
};
#endregion
Expand Down Expand Up @@ -1039,12 +1028,6 @@ public static FormulaValue BlankToEmptyString(IRContext irContext, FormulaValue[

return args[0];
}

public static FormulaValue PrimitiveToSingleColumnRecord(IRContext irContext, FormulaValue[] args)
{
var record = FormulaValue.NewRecordFromFields(new NamedValue("Value", args[0]));
return record;
}
#endregion
}
}

0 comments on commit f79b5ab

Please sign in to comment.