-
Notifications
You must be signed in to change notification settings - Fork 979
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
fix: reorder named arguments to match declaration order #1949
fix: reorder named arguments to match declaration order #1949
Conversation
…guments to match declaration order.
|
This is a great addition, thanks @kevinclancy Could we add a few unit tests? |
Sure, @montyly . I just added a couple of tests. |
slither/slithir/convert.py
Outdated
assert isinstance(args, list) | ||
assert isinstance(call_names, list) | ||
assert isinstance(decl_names, list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these can be removed since the function signature is typed and indicates this
slither/slithir/convert.py
Outdated
if isinstance(ins, InternalDynamicCall): | ||
return [p.name for p in ins.function_type.params] | ||
|
||
assert isinstance(ins, EventCall) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this assertion for? Should EventCall
return an order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suppose that someone were to add a new subclass of Call
in the future. In this case, we would want to add another clause to this function to handle the new subclass. If we forget to do that, this assertion will get hit, at which point it will be obvious that we missed a case.
The assertion communicates that we intend for this function to exhaustively handle all subclasses of Call
without implicitly folding any unmentioned subclasses into the code handling EventCall
.
Another way to write this would be:
if isinstance(ins, HighLevelCall):
...
... more cases here ...
else isinstance(ins, EventCall):
...
else:
assert False
Ideally, the EventCall
case would return an order, but I'm not sure how to obtain the correct order. We can create a new issue for this mentioning that parameter reordering is still broken for EventCall
, NewContract
, and HighLevelCall
s that do not have a function
field.
slither/slithir/convert.py
Outdated
if isinstance(ins, (LowLevelCall, NewElementaryType, NewArray)): | ||
# named arguments are incompatible with these call forms | ||
assert False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we update the function signature to only be subclasses of call which are accepted and remove this? We can add an assertion like assert isinstance(ins, NewStructure, NewContract... )
, too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be better to add assert not isinstance(LowLevelCall, NewElementaryType, NewArray)
at the top of the get_declared_param_names
function.
We could also make the assert False
case return None
instead. Of course, it would be a hassle to get test coverage for this.
…ared_param_names to its call site. Removed assertions from reorder_arguments
Fixes #1906
A function call with explicitly named parameters, of the form
f({argName1: arg1, ...})
, may list the parameters in an order different from that of the function's declaration. In this case, the IR should reorder the arguments to match the function declaration order before generating IR.In practice, I have only seen named argument calls for struct constructors, so I suspect they are the only form that is documented. For calls to built-in functions, contract constructors, and dynamic internal function calls, named arguments produce confusing type checking errors. For all other forms of function calls, named arguments work, but I've never seen them used in a real project.
This PR implements named argument reordering for the following forms of function calls:
For the following forms of function calls, the order of the declaration arguments is not directly available during IR generation, so the PR did not implement reordering for them:
The
get_declared_param_names
function returnsNone
for these unimplemented call forms.Example
Output Before:
Output After