Skip to content

Support objects in expressions#1777

Open
TomasEng wants to merge 12 commits into
support-lists-in-expressionsfrom
support-objects-in-expressions
Open

Support objects in expressions#1777
TomasEng wants to merge 12 commits into
support-lists-in-expressionsfrom
support-objects-in-expressions

Conversation

@TomasEng

@TomasEng TomasEng commented May 28, 2026

Copy link
Copy Markdown
Contributor

Important

This pull request is stacked upon #1769, which should be merged first.

Description

This pull request adds support for objects in expressions, along with an object function for creating an object. Here is an overview of the changes:

  • New object function in ExpressionEvaluator. Because of the complexity of the function, I created a separate class named ObjectFunctionEvaluator for evaluating the function.
  • Support for dictionaries in ExpressionValue. Most of the code did already exist, hiding in comments.

Here is the corresponding change in App frontend: Altinn/altinn-studio#18982

Related Issue(s)

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing not possible since there is no use case for this until we add functions that accept objects as parameters; the automated unit tests should be sufficient
  • Relevant automated test added (if you find this hard, leave it and we'll help out)
  • All tests run green

Documentation

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ecbdc9f6-682f-45e5-a0f6-0c6874bb8910

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch support-objects-in-expressions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@TomasEng TomasEng added feature Label Pull requests with new features. Used when generation releasenotes backport-ignore This PR is a new feature and should not be cherry-picked onto release branches labels May 28, 2026
@TomasEng TomasEng force-pushed the support-objects-in-expressions branch from 5a4dacc to 5c9c571 Compare May 28, 2026 13:12
@TomasEng TomasEng added the squad/data Issues that belongs to the named squad. label May 29, 2026
@TomasEng TomasEng moved this to 👷 In progress in Team Altinn Studio May 29, 2026
@TomasEng TomasEng force-pushed the support-objects-in-expressions branch from 2fb14e2 to ee69ba5 Compare May 29, 2026 07:00
Comment on lines +233 to +235
#pragma warning disable CA1720
@object,
#pragma warning restore CA1720

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sonar complained about this variable having a name that contains "object", but we need this for the object function to work.

@TomasEng TomasEng force-pushed the support-objects-in-expressions branch 2 times, most recently from 4908de3 to 2a553d2 Compare May 29, 2026 07:33
@TomasEng TomasEng force-pushed the support-objects-in-expressions branch from 2a553d2 to ab5d0b1 Compare May 29, 2026 07:40
@TomasEng

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@TomasEng TomasEng marked this pull request as ready for review May 29, 2026 08:02
@TomasEng TomasEng moved this from 👷 In progress to 🔎 In review in Team Altinn Studio May 29, 2026
TomasEng added 3 commits June 1, 2026 08:49
…to support-objects-in-expressions

# Conflicts:
#	src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs
#	test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
@TomasEng TomasEng mentioned this pull request Jun 3, 2026
5 tasks
@olavsorl olavsorl self-assigned this Jun 9, 2026

@olavsorl olavsorl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kjørte claude på denne også, stortsett bare pirking. Fant noe selv også. Sikkert fint om du får @ivar til å se over også


namespace Altinn.App.Core.Internal.Expressions;

internal sealed class ObjectFunctionEvaluator

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du laget vell en mappe for disse klassene som vi diskuterte i den andre PRen?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja, den blir opprettet i PR-en for Jmespath. Her har vi bare én slik klasse, så da tenker jeg uansett ikke at det er nødvendig med en egen mappe.

JsonValueKind.False => "false",
JsonValueKind.String => String,
JsonValueKind.Number => Number.ToString(CultureInfo.InvariantCulture),
// JsonValueKind.Object => JsonSerializer.Serialize(Object),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hva med denne, utenfor scope?

@TomasEng TomasEng Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja. Så vidt jeg forstår brukes den når man caster til streng, og det er ikke noe vi støtter for objekter (i hvert fall ikke foreløpig).

Comment thread src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs Outdated

/// <summary>Get the value as an object (or throw if it isn't an object ValueKind)</summary>
public Dictionary<string, ExpressionValue> Dictionary =>
public JsonObject Dictionary =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bør kanskje rename Dictionary, nå når det ikke er en Dictionary lenger?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kalte den det fordi Sonar klagde på "Object". Har du noen andre forslag?

public ObjectFunctionEvaluator(ExpressionValue[] args) => _args = args;

public Dictionary<string, ExpressionValue> Evaluate()
public JsonObject Evaluate()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude skriver:

LINQ density (style nit): ObjectFunctionEvaluator.Evaluate makes several passes over _args (Where ×2, Distinct, Zip, ToDictionary). Fine for the tiny arg counts expected, but AGENTS.md notes "sometimes a for loop is just as good as LINQ" — a single loop could build the dict, detect odd-count, dup keys, and bad key types in one pass. Optional.

@TomasEng TomasEng Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeg kan ikke se hvordan en løkke vil gjøre dette mer oversiktlig. Løkker er vanskelige å lese. Verktøy som CodeQL foreslår jo ofte å bytte ut løkker med nettopp Linq. Jeg kan eventuelt dele opp i flere funksjoner, for eksempel ExtractEvenArguments og ExtractOddArguments for Where-biten.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La til disse metodene nå. Det ble mer ryddig.

Comment thread src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs Outdated
Comment thread src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs Outdated
{
throw new JsonException("Expected StartObject token.");
}
var values =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Småpirk, men values i flertallsform henger sikkert igjen fra dette var Dictionary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fikset.

}
var values =
JsonSerializer.Deserialize<JsonObject>(ref reader, options)
?? throw new JsonException("Expected EndObject token.");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er det riktig å anta at dersom Deserialize returnerer null så mangler endObject token, finnes det ikke andre tilfeller der Deserialize kan returnere null?

@TomasEng TomasEng Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nei, Deserialize feiler vel uansett hva som det er som gjør at verdien ikke kan omgjøres til JsonObject. Godt sett! Skal gjøre feilmeldingen mer riktig.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fikset.

Comment thread src/Altinn.App.Core/Models/Expressions/ExpressionFunction.cs Outdated
@TomasEng TomasEng requested a review from olavsorl June 10, 2026 07:19
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-ignore This PR is a new feature and should not be cherry-picked onto release branches feature Label Pull requests with new features. Used when generation releasenotes squad/data Issues that belongs to the named squad.

Projects

Status: 🔎 In review

Development

Successfully merging this pull request may close these issues.

2 participants