Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement special handling of subapplications when collecting MethodCallInfo #9677

Merged
merged 4 commits into from
Apr 16, 2024

Conversation

vitvakatu
Copy link
Contributor

Pull Request Description

Fixes on of the issues in #9354

Stale method call info for inner sub-application was causing additional argument placeholders on the node for certain expressions. Now it is fixed:

  1. We only create function widget for the most top-level expression in the prefix application chain.
  2. We reuse method call info from inner expressions, assuming it will be always correct for our purposes.
subapplications.mp4

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
  • All code follows the
    Scala,
    Java,
    and
    Rust
    style guides. In case you are using a language not listed above, follow the Rust style guide.
  • All code has been tested:
    • Unit tests have been written where possible.
    • If GUI codebase was changed, the GUI was tested when built using ./run ide build.

@vitvakatu vitvakatu added --bug Type: bug -gui labels Apr 11, 2024
@vitvakatu vitvakatu self-assigned this Apr 11, 2024
notAppliedArguments: correctedNotAppliedArguments.sort().slice(appliedArgs),
},
suggestion: info.suggestion,
partiallyApplied: info.partiallyApplied,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

On self-review I noticed that I’m not doing anything with this field. The issue is that I don’t quite understand its purposes and how it should be changed for outer expressions when it’s coming from inner ones.

@vitvakatu vitvakatu mentioned this pull request Apr 11, 2024
Copy link
Contributor

@farmaazon farmaazon left a comment

Choose a reason for hiding this comment

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

LGTM, except I'm not sure about this partiallyApplied field. @Frizi you seem to be an author of it, can you take a look?

return {
methodCall: {
...info.methodCall,
notAppliedArguments: correctedNotAppliedArguments.sort().slice(appliedArgs),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why is sort necessary here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we have a guarantee that the list coming from the engine side will always be sorted? There is no such thing in the documentation, although it seems to be the current behavior.

Comment on lines 436 to 443
// No info, continue recursion to the next sub-application AST.
if (ast instanceof Ast.App) {
if (ast.argumentName)
return get(ast.function, appliedArgs, [...appliedNamedArgs, ast.argumentName.code()])
return get(ast.function, appliedArgs + 1, appliedNamedArgs)
}
}
return get(ast, 0, [])
Copy link
Contributor

Choose a reason for hiding this comment

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

This function could easily be a loop. That should be easy to transform, since currently it is always a tail recursion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines +192 to +199
{
description: '1 named & 1 unnamed args.',
code: 'Aggregate_Column.Sum as=x y',
subapplicationIndex: 2,
notAppliedArguments: [0, 1],
expectedNotAppliedArguments: [],
},
] as TestCase[])(
Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure to also add a test case with notAppliedArguments being "incorrectly" empty, which afaik is the actual response we get from engine for constructors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 326 to 328
if (prevFunctionState != null && info?.partiallyApplied === true && ast instanceof Ast.Ident) {
return Score.Mismatch
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The purpose of that condition and partiallyApplied property was to avoid rendering the argument lists twice in specific case of calling partially applied function from another node:

node1 = some_func arg3=baz
node2 = node1 foo bar

Since node1 inside node2 expression itself has a Function type and presents a list of non-applied arguments, those used to be rendered again. With your changes and the prefixCalls test above, this condition might no longer be necessary. If that's true, the whole partiallyApplied info could be completely removed as well. That would also save us from calling getMethodCallInfo in the score function, which is really neat.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for explanation. My testing showed that partiallyApplied check is indeed redundant for us. I don’t think we can get rid of getMethodCallInfo – otherwise we would not build a function widget in case of node2 = node1. Below is behavior after my changes:

When no arguments applied to the second node (node2 = node1):

Screenshot 2024-04-12 at 3 54 37 PM

When arguments applied to the second node (node2 = node1 path):

Screenshot 2024-04-12 at 3 56 49 PM

I think it looks correct.

app/gui2/src/providers/functionInfo.ts Outdated Show resolved Hide resolved
@vitvakatu vitvakatu requested a review from Frizi April 12, 2024 12:12
@@ -521,7 +521,7 @@ const baseMockNode = {
conditionalPorts: new Set(),
} satisfies Partial<Node>

function mathodCallEquals(a: MethodCall | undefined, b: MethodCall | undefined): boolean {
export function mathodCallEquals(a: MethodCall | undefined, b: MethodCall | undefined): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why export? This doesn't seem to be used anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, but I still think it can become useful in the future, so I don’t want to remove it. export is a way of disabling unused linter warning.

Copy link
Contributor

Choose a reason for hiding this comment

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

In general I would prefer to remove unused code, unless you have a specific use in the future in mind for it.

@vitvakatu vitvakatu added CI: Ready to merge This PR is eligible for automatic merge CI: No changelog needed Do not require a changelog entry for this PR. labels Apr 16, 2024
@mergify mergify bot merged commit 7e34507 into develop Apr 16, 2024
36 of 38 checks passed
@mergify mergify bot deleted the wip/vitvakatu/applications branch April 16, 2024 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
--bug Type: bug -gui CI: No changelog needed Do not require a changelog entry for this PR. CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants