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

Python: Move min/maxParameter methods to Function class #18871

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

tausbn
Copy link
Contributor

@tausbn tausbn commented Feb 26, 2025

These seem generally useful outside of points-to, and so it might be better to add them to the Function class instead.

I took the liberty of renaming these to say Arguments rather than Parameters, as this is more in line with the nomenclature that we're using elsewhere. (The internal points-to methods retain the old names.)

I'm somewhat ambivalent about the behaviour of getMaxParameters on functions with *varargs. The hard-coded INT_MAX return value is somewhat awkward, but the alternative (to only have the predicate defined when a specific maximum exists) seems like it would potentially cause a lot of headaches.

These seem generally useful outside of points-to, and so it might be
better to add them to the `Function` class instead.

I took the liberty of renaming these to say `Arguments` rather than
`Parameters`, as this is more in line with the nomenclature that we're
using elsewhere. (The internal points-to methods retain the old names.)

I'm somewhat ambivalent about the behaviour of `getMaxParameters` on
functions with `*varargs`. The hard-coded `INT_MAX` return value is
somewhat awkward, but the alternative (to only have the predicate
defined when a specific maximum exists) seems like it would potentially
cause a lot of headaches.
@tausbn tausbn marked this pull request as ready for review February 26, 2025 14:57
@Copilot Copilot bot review requested due to automatic review settings February 26, 2025 14:57
@tausbn tausbn requested a review from a team as a code owner February 26, 2025 14:57

Choose a reason for hiding this comment

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

PR Overview

This PR moves the min/max parameter methods to the Function class and renames them to use “Arguments” for consistency with the rest of the codebase.

  • Moved methods from a points-to context into the Function class.
  • Renamed the methods to getMinArguments and getMaxArguments, and updated the corresponding change notes.

Reviewed Changes

File Description
python/ql/lib/change-notes/2025-02-26-add-get-min-max-parameters-to-function-class.md Added change notes documenting the new Function class methods

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

Tip: Copilot only keeps its highest confidence comments to reduce noise and keep you focused. Learn more

Copy link
Collaborator

@adityasharad adityasharad left a comment

Choose a reason for hiding this comment

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

Generally looks good, stylistic questions only.

@@ -163,6 +163,18 @@ class Function extends Function_, Scope, AstNode {
ret.getValue() = result.getNode()
)
}

/** Gets the minimum number of positional arguments that can be correctly passed to this function. */
int getMinArguments() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Naming: Should these be getMinPositionalArguments, something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a mouthful (and it suggests the existence of getMinKeywordArguments, which I'm not entirely sure makes sense), but it's probably a good idea to proactively disambiguate things here. At the very least, renaming it to something shorter will be easy to do if we feel like it.

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 in 11e6194.

/** Gets the maximum number of positional arguments that can be correctly passed to this function. */
int getMaxArguments() {
if exists(this.getVararg())
then result = 2147483647 // INT_MAX
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ooh this is an interesting trap. I suggest at least putting it in the QLDoc, i.e. if the function doesn't take varargs, the result is INT_MAX.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you've got a superfluous negation there (if the function does take varargs, the result is INT_MAX), but I agree this should be documented better.

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 in 11e6194.

joefarebrother
joefarebrother previously approved these changes Feb 28, 2025
Copy link
Contributor

@joefarebrother joefarebrother left a comment

Choose a reason for hiding this comment

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

Looks good 👍

@yoff
Copy link
Contributor

yoff commented Mar 4, 2025

I'm somewhat ambivalent about the behaviour of getMaxParameters on functions with *varargs. The hard-coded INT_MAX return value is somewhat awkward, but the alternative (to only have the predicate defined when a specific maximum exists) seems like it would potentially cause a lot of headaches.

Perhaps here it is appropriate to define a newtype and force users to deal with the two cases explicitly?

@tausbn
Copy link
Contributor Author

tausbn commented Mar 4, 2025

I'm somewhat ambivalent about the behaviour of getMaxParameters on functions with *varargs. The hard-coded INT_MAX return value is somewhat awkward, but the alternative (to only have the predicate defined when a specific maximum exists) seems like it would potentially cause a lot of headaches.

Perhaps here it is appropriate to define a newtype and force users to deal with the two cases explicitly?

I thought about it for a bit, and I think for the moment it's fine to just use INT_MAX. It's slightly overkill (we're unlikely to see a call with a thousand arguments, much less two billion), but in cases where this might give weird results, it's easy to filter away by looking for the presence of a varargs parameter. By preserving the current semantics, at least comparisons of the number of arguments will make sense (which is the only use case we have at the moment).

Renames the methods to include the word `Positional`, and adds
documentation for the behaviour of `getMaxPositionalArguments` when the
function in question has a `*varargs` parameter (and hence no upper
limit on the number of arguments).
is_quad_op(name) and result = 4
}

predicate declaredAttributeVar(Class cls, string name, EssaVariable var) {

Check warning

Code scanning / CodeQL

Dead code Warning

This code is never used, and it's not publicly exported.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants