-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Editorial: Extract operation 'ParsePattern' #1866
Conversation
Yeah, that seems a little unfortunate. What would you think about returning |
Well, any value that can be distinguished from a Parse Node would work, but I think it'd be better to follow the example of ParseScript and ParseModule |
I think the inconsistency of returning a completion from an operation used in static semantics bothers me more.
Eh, I think implementations can figure out the appropriate error to give without using having to pass around error objects. All considered I think I would still prefer returning |
Huh? I mean, I understand that returning a completion record bothers you, but I'm not sure how that's relevant to the suggestion to return a List of errors.
I'd advise against using |
(force-pushed to resolve a merge conflict) |
A List of Errors is fine by me and the other editors; let's go with that. |
(force-pushed to resolve merge conflicts and change the return-type to list-of-errors) |
spec.html
Outdated
1. Let _patternText_ be the result of interpreting each of _P_'s 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not applied to the elements. | ||
1. Let _patternCharacters_ be a List whose elements are the code unit elements of _P_. | ||
1. Let _parseResult_ be ParsePattern(_patternText_, _u_). | ||
1. If _parseResult_ is a List of *SyntaxError* objects, throw a *SyntaxError* exception. |
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 if it's a List of something else, or an empty List?
It seems like ParsePattern
returns either a Parse Node, or not - should this be "is not a Parse Node"?
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 returns either a Parse Node or a List of SyntaxError objects. There's no other case.
We could follow this with an Assert: _parseResult_ is a Parse Node
, if you think that's valuable.
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.
Fair, it just seems too vague to me to assert that it's a List of syntax error objects (without also reading the abstract operation), because of the possibilities that implies.
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.
@ljharb Would adding Assert: _parseResult_ is a Parse Node
as the following line resolve your concern?
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 I'd prefer changing the condition to "is not a Parse Node", as suggested by @ljharb. It's semantically equivalent, but easier on the reader: you don't need to look at the definition of ParsePattern to know that the only other possibility is that it's a Parse Node. (And we don't need to Assert that it is.)
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.
In that case, should we say "throw one of the items in the list as an exception"? The impl has control of what's in the list anyways, so it wouldn't be normative, but would convey the intention you find important.
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.
There's a little bit of awkwardness there in that for that to be sensible the list has to be non-empty. Which it is guaranteed to be by the implementation of ParsePattern, but you have to look there to know that.
I'd be fine with that, I guess, but would still personally weakly lean towards the If _parseResult_ is a List of *SyntaxError* objects, throw a *SyntaxError* exception
form + an assert.
But any of the suggestions here are adequate. I would mostly like us to just pick one and land it.
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 it's valuable to follow up this step with an assertion. I don't care which way around the test is.
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 feel like any reasonable non-formalist reading of "a List of x objects" excludes the vacuous empty List case, but it doesn't hurt to qualify "a non-empty List of x objects", I guess.
And I agree with @bakkot on:
I kind of prefer writing it this way because it suggests that the error thrown could be one of the errors in the list
So I'd prefer directly talking about errors than asserting it's not a parse node.
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 should add I'm happy with an additional assert, but I like the condition for throwing checking for a list of errors over checking for not being a parse node.
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 didn't review too closely to ensure correctness. I gladly trust @bakkot's existing review here that this is correct.
Editorially lgtm with rename for abstract closure.
spec.html
Outdated
1. Let _patternText_ be the result of interpreting each of _P_'s 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not applied to the elements. | ||
1. Let _patternCharacters_ be a List whose elements are the code unit elements of _P_. | ||
1. Let _parseResult_ be ParsePattern(_patternText_, _u_). | ||
1. If _parseResult_ is a List of *SyntaxError* objects, throw a *SyntaxError* exception. |
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 feel like any reasonable non-formalist reading of "a List of x objects" excludes the vacuous empty List case, but it doesn't hurt to qualify "a non-empty List of x objects", I guess.
And I agree with @bakkot on:
I kind of prefer writing it this way because it suggests that the error thrown could be one of the errors in the list
So I'd prefer directly talking about errors than asserting it's not a parse node.
spec.html
Outdated
1. Set _obj_.[[OriginalSource]] to _P_. | ||
1. Set _obj_.[[OriginalFlags]] to _F_. | ||
1. Set _obj_.[[RegExpMatcher]] to the abstract closure that evaluates the above parse by applying the semantics provided in <emu-xref href="#sec-pattern-semantics"></emu-xref> using _patternCharacters_ as the pattern's List of |SourceCharacter| values and _F_ as the flag parameters. | ||
1. Set _obj_.[[RegExpMatcher]] to the abstract closure that evaluates _parseResult_ by applying the semantics provided in <emu-xref href="#sec-pattern-semantics"></emu-xref> using _patternCharacters_ as the pattern's List of |SourceCharacter| values and _F_ as the flag parameters. |
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.
Please do a s/abstract closure/Abstract Closure/g
. We recently capitalized it to be consistent with other spec types.
force-pushed to:
|
@jmdyck would you like to rebase this down to a single commit with a nicer commit message than me naively concatenating them? :-) |
Thanks for the offer. I decided that there wasn't much benefit to enumerating the refactoring steps in the final commit message, but I'll do so here: IsValidRegularExpressionLiteral:
RegExpInitialize:
Extract operation 'ParsePattern' IsValidRegularExpressionLiteral:
|
... from common code in IsValidRegularExpressionLiteral and RegExpInitialize. (This was originally presented as a series of 12 small refactorings. For more info, see the PR page.)
... from common code in IsValidRegularExpressionLiteral and RegExpInitialize.
This is the refactoring I referred to over here.
I've split the PR into a series of smaller refactorings so that it's easier to follow. I expect these will be squashed together at merge, so I didn't bother prefixing their commit messages with "Editorial:". (Except for the final commit, whose commit message can serve as the message for the squash.)
IVREL = IsValidRegularExpressionLiteral, REI = RegExpInitialize
Note that if the parse fails, ParsePattern returns an abrupt completion. This is somewhat odd when it's being called by IsValidRegularExpressionLiteral, because the latter is static semantics. (Its only invocation is from an early error). IsValidRegularExpressionLiteral translates the abrupt completion into
*false*
, so the abrupt completion doesn't go any further, but you might object to it even existing during static semantics processing. If that's a sticking point, we can replace the abrupt completion with a SyntaxError object or a List of them (as in ParseScript or ParseModule).