Fix function parsing with ambiguous lists in parameters. #6579
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Upon failing to parse a function (with too few arguments) Skript will re-attempt it explicitly as an ExpressionList of arguments.
This fixes
func(uuid of player, "hello")
being wrongly-interpreted asfunc(uuid of (player, "hello"))
and failing to parse.Note: the Git diff is a nightmare because the methods in SkriptParser are nine million lines long, I can't do anything about that, sorry 😦
The problem
Functions struggle with ambiguous parameters: is
func(uuid of {_a}, {_b})
asking for a function with two parameters (uuid of {_a}
and{_b}
) or is it asking for a function with a single parameter (uuid of {_a} and {_b}
)?Most rational people would say the first, but Skript does not think so! Lists are checked after singular expression parsing (for arguably good reason), so
uuid of {_a} and {_b}
will be matched first.This means that your function
func(uuid: string, something: string)
will fail.This on its own is fine. Everything here is intended, however we have a secret enemy: string converters!
Since 2.6 we are in an era where a string can be anything it wants. This means that while
uuid of "hello"
ought to fail (because how can a text have a UUID?) the text can be implicitly converted to a World, which can have a UUID.This means that even nonsensical stuff like
uuid of {_a}, "have a nice day!"
is technically admissible at parse time.Converters bring us lots of nice things, but they've also exacerbated this issue with function parsing, because it's even harder for us to identify a mistake.
My Lovely(ish) Solution
My fix is as follows:
If the function fails -- specifically because it has too few parameters -- the arguments string is reparsed as only a list of expressions, and then it's tested again. If it still fails, oh well.
This isn't perfect: obviously it's a second needless check for things that are actually just wrong, but that's not the end of the world.
It also can't fix parsing ambiguity mid-way through the arguments:"hello", uuid of {_a}, "there"
is still gonna be parsed the wrong way because that's how Skript parses stuff, and we probably shouldn't change that.Walrus said it's fine 🙂
Target Minecraft Versions: any
Requirements: none
Related Issues: closes #4988