This pr handles few things that are mentioned below:
1) It adds a new virtual overload of `GetDefaultBindingConfig` in
Engine.cs that takes in ParserOptions and optional rule scope and
returns a binding config that is used by `Engine.ComputeBinding()`. This
is done so that Power Apps can supply custom binding config for semantic
tokenization. Power Apps never set
`BindingConfig.UseThisRecordForRuleScope` to true but changes before
this pr calculated the value of
`BindingConfig.UseThisRecordForRuleScope` based on the value returned
from `Engine.GetRuleScope()`. It would be true when GetRuleScope()
returns a non null value. There are properties such as `OnErrors `on
AppInfo control in PowerApps that returns a non null value for
`GetRuleScope()`. In this case,` useThisRecordForRuleScope `would be
true in` Engine.ComputeBinding() `but it should never be true when
`Engine.ComputeBinding() `is run from PowerApps.
2) This pr fixes a bug where duplicate string interpolation and island
tokens were added when expression has nested string interpolation to the
list of tokens returned from Tokenization.Tokenize. This pr fixes that
logic and adds tests to validate it. A good example of this bug is an
expression like `$"{$"{$"{$"{.12e4}"}"}"}"`. The number of tokens should
be 17 but it is 41. Many of them are duplicate with same spans and token
types.
3) This pr also fixes one test that happened due to Visual Studio
picking up a different line feed for C# multiline strings `@""` .
Updates the test to avoid using multiline string. @gregli-msft is the
only and first one so far to face this problem. Tests were failing for
him. Confirmed with him that avoiding multiline string fixes the test.
add guard to catch bugs in host where it calls a single-threaded region
on multiple threads.
---------
Co-authored-by: Mike Stall <jmstall@microsoft.com>
Translation handback check-in (PR Created by automation).
Co-authored-by: Luc Genetier <69138830+LucGenetier@users.noreply.github.com>
Co-authored-by: Mike Stall <mikestall@hotmail.com>
Currently the Switch and IfError functions use an intersection rule for the arguments - Switch(var, 1, {a:1}, {b:2}) returns an empty record since there are no common properties in the two records. With the PowerFxV1 rules, we are changing it to follow the "union with first-type rule" that is used in other functions, so the type of that expression would be ![a:n] with the new feature.
This is similar to #1507 which did the change for the If function.
Fix issue: https://github.com/microsoft/Power-Fx/issues/1367
Problem this PR fix:
Start from 1e+16 to 1e+20, current mod_float return 0 for most of the
case (mostly wrong value). And overflow from 1e+21 or higher.
This PR use C# % function to do mod for the wrong/overflow issues.
Note on PA (Need to fix as well): mod result is always 0 from 1e18 (mod
123). So, it shared the same problem. mod result is wrong for > 1e17. It
did not return overflow error for 1e306 but return 0 (wrong value).
---------
Co-authored-by: Carlos Figueira <carlosff@microsoft.com>
If a ForAll expression is used within a context where its result is not needed, then it should be able to use void expressions, like in the example below. This change allows it, making the entire result of the ForAll expression a void result.
ForAll(
Sequence(4),
If(
Mod(Value, 2) = 1,
Patch( table, Index(table, Value), { IsOdd: true } ), // this returns a
record, incompatible with tables
Collect( table, { Value: Value, IsOdd: false }, { Value: Value + 1,
IsOdd: true } // this returns a table
)
)
Threading tests to help enforce #1519 .
Includes a bunch of little fixes and reducing failure list.
Tests don't aggressively assert yes, too many failures. But we can at
least run and drive to 0.
---------
Co-authored-by: Mike Stall <jmstall@microsoft.com>
Currently the Patch/Collect functions can update values that should be immutable (like scope variables defined in a With record). This change defines a "mutable" concept in the binder, which can be checked by mutation functions so that they won't update those values.
1. Allow pattern for adding new user properties. So switch to a class
instead of interface so it's non-breaking. List is still curated by Fx
team, so we want a class (with well defined property names) and not a
property bag.
2. Allow static enforcement for the subset of properties a host
provides.
3. Dynamic population - some properties require a network call, and this
needs to be lazily done.
Achieve these via a custom derived RecordValue that wraps a UserInfo
provided by the serviceProvider.
Include a helper, BasicUserInfo, for implementing the common paths.
---------
Co-authored-by: Mike Stall <jmstall@microsoft.com>
Earlier this week, Customer reached out to us about a bug when trying to
format the expression like "Set(Children; true)" in the formula bar.
"Children" is not a reserved keyword and unless the disabled reserved
keyword flag is not set when invoking Lexer, "Children" gets identified
as an ErrorToken. This causes errors in the AST and we don't format when
there are errors and just return the same expression.
To solve this, we need to pass in a Flags.DisabledReservedKeyword flag
to the parser and ultimately lexer when invoking them before the pretty
printing. There was no ability to pass in custom flags so I extended the
"Format" function (which is an entry point for pretty printing) with an
optional argument to allow passing custom flags. These changes would be
later consumed in Canvas Apps Backend (Would be passing in
Flags.DisabledReservedKeyword | Flags.EnableExpressionChaining to Format
in Canvas Apps Backend)
@gregli-msft Could you take a look at this and see if this is the right
way to solve it
Currently the If function uses an intersection rule for the arguments - `If(varBool, {a:1}, {b:2})` returns an empty record since there are no common properties in the two records. With the PowerFxV1 rules, we are changing it to follow a union rule, with "first-type preference" that is used in other functions like Table, so the type of that expression would be `![a:n,b:n]` with the new feature.
Addresses #1497
The support for semantic tokenization was added in PR
https://github.com/microsoft/Power-Fx/pull/1420. I migrated the logic
behind tokenization in old formula bar from Canvas App backend to
PowerFx. In doing so, i forgot to bring over a very tiny part but
important for old formula bar of the logic that computes whether first
name tokens can be hidden or not.
Follow-up to #1489 - using the 'only coerce to left type' on the Table function either if StronglyTypedEnums is enabled (the root cause of the bug it fixed), or if we are using the Power Fx V1 compat rules (since it moved to a "first-type" rule)
We have update the Table function (and the `[...]` syntax) to favor the first type. But the current union logic would allow coercion from the first value into subsequent ones, which would cause issues like in the example `[ErrorKind.Div0, 12]` - the resulting type is `![Value:ErrorKindOptionSet], but the IR would try to coerce the data to number (since numeric option set can be coerced to number, but not the other way around). This change forces, within those contexts, that the union should only happen to the left type, not the right one.
Fixes#1477
Co-authored-by: Carlos Figueira <carlosff@microsoft.com>
Co-authored-by: Carlos Figueira <carlosfigueirafilho@hotmail.com>
Co-authored-by: Mike Stall <mikestall@hotmail.com>
Added arg index to udf params, we need this during code gen on the host.
Created a new info type for UDF parameters.
Modified UserDefinitionsNameResolver to not use record type, since I
didn't find a way to get the index of a pram.
This change brings the named formula to the same consistency for
delegation warnings and marks the expression as non-delegable if it's a
part of non-delegable expression.