[ 
https://issues.apache.org/jira/browse/GROOVY-12425?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18128784#comment-18128784
 ] 

ASF GitHub Bot commented on GROOVY-12425:
-----------------------------------------

daniellansun commented on PR #2944:
URL: https://github.com/apache/groovy/pull/2944#issuecomment-6269318424

   @paulk-asert Thank you for tracing this against the grammar. The false 
positive on division at end of file was real. The fix follows that direction, 
with one narrowing so expression-introducing keywords still accept a slashy 
string.
   
   ## Division after a value
   
   `String.class / 2` and `String.class /2/ 3` are division again, including at 
end of file. Keywords that can end a value and do not introduce an expression 
(`class`, `super`, `var`, `int`, `new`, and the rest of that set in 
`REGEX_CHECK_SET`) are division operands. That also corrects the old two-slash 
mislex of `a.class /2/ b`.
   
   `return`, `assert`, `throw`, `case`, `yield`, `await`, `defer`, `else`, and 
`do` stay out of that set. Putting them in would reject programs that compile 
today: `return /pattern/`, `assert /pattern/`, `'ab' in /a/`, `else /pattern/`, 
and `do /pattern/ while (false)`. After a member selector the same keyword is a 
name, so these are division:
   
   - `obj.return / 2`
   - `obj.<T>return / 2`
   - `obj.<@Ann(x > 1) T>return / 2`
   
   Newlines and comments between the selector and the name are ignored. `<...>` 
in between is part of the member, including a qualified name. `>`, `>>`, and 
`<` inside `()`, `[]`, or `{}` on an annotation do not close that type argument.
   
   `in` is infix when a value precedes it. `'ab' in /a/`, `in in /a/`, `obj.in 
in /a/`, and `for (in in /a/)` stay slashy strings. A member name counts as 
that value. A bare name does not: `in / 2`, `obj.in / 2`, and `return in / 2` 
are division.
   
   `yield`, `await`, and `defer` are not treated as values. `yield in / 2` 
stays division rather than `Unclosed string literal`. The cost is that `for 
(yield in /a/)`, and the same form for `await` and `defer`, is not a slashy. 
Happy to flip that tradeoff if the for-variable form is the one you want to 
keep.
   
   ## Unclosed slashy GString
   
   `/hello $name` with no closing `/` is `SlashyGStringBegin`, not the plain 
EOF alternative. The message stays `Unexpected end of input` at the end of the 
line, not `Unclosed string literal` on the opening `/`. That limitation is now 
in the lexer comment and in `core-grammar.adoc`, and the current text is pinned 
by tests. Unclosed `$/...` is unchanged: an EOF alternative there would reject 
`($/2)`, so it still has none.
   
   ## `requireNonNull`
   
   The `Objects.requireNonNull` around `visitFormalParameters` in 
`transformRecordHeaderToProperties` is removed. `visitFormalParameters` already 
returns `Parameter.EMPTY_ARRAY`, and the check was not part of this diagnostic 
change.
   
   ## `reset()`
   
   `Lexer.setInputStream` still drops lexer state only through `reset()`. The 
new member-name flags are cleared there, so a reused lexer does not keep a 
pending `.` or a previous `class` operand. Worth a separate mention in the 
JIRA, as you suggested. I have not edited the JIRA from here.
   




> Refine error message for unclosed type argument and unclosed slashy string
> --------------------------------------------------------------------------
>
>                 Key: GROOVY-12425
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12425
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Priority: Major
>
> h2. Description
> Two parser diagnostics name a missing closer but point at the wrong token, or 
> name a different mistake. Both should match the caret already used for an 
> unclosed quote: one sentence, on the token that is wrong.
> h3. Unclosed type argument
> {{List<Integer name}} is parsed as the comparison {{List < Integer}} plus a 
> following argument list. The message was already {{Missing '>'}}, which is 
> the same advice as javac's {{> or ',' expected}}. The caret sat on {{List}}, 
> often many tokens away from the missing {{>}}.
> The caret now sits on the first token of that argument list. An identifier 
> after {{T < U}} is an argument list, not a command argument, so the caret is 
> the start of the list. Extra spaces do not pull it back onto the space after 
> the type argument.
> * {{List<Integer list2}} — caret on {{list2}}
> * {{List<List<Integer> list2}} — caret on {{list2}}, after the inner {{>}}
> * {{List<Integer  name}} — two spaces; caret on {{name}}, not on the first 
> space
> * {{List < Integer 1, 2}} — caret on {{1}}
> * {{List < Integer name foo}} — caret on {{name}}, not on {{foo}}
> A comparison that is not two type names stays {{Unexpected input}}. {{list < 
> Integer name}} is one of those.
> {noformat}
> Missing '>' @ line 1, column 14.
>    List<Integer list2 = new ArrayList<Integer>()
>                 ^
> {noformat}
> h3. Unclosed slashy string
> An unclosed {{/.../}} was reported as {{Unexpected input: '/'}}. {{/}} is 
> also the division operator, so a slashy string that never closes fell through 
> to that token.
> It is now {{Unclosed string literal}}, with the caret on the opening {{/}}. 
> That is the same sentence and the same opener caret as an unclosed {{'}} or 
> {{"}}, and the same place javac marks {{unclosed string literal}}.
> {noformat}
> Unclosed string literal @ line 1, column 5.
>    s = /hello
>        ^
> {noformat}
> The same message is used when the slashy string is only {{/}} at end of 
> input, and when the opener is on the line after {{=}}.
> Division is unchanged:
> * {{a / b}} stays division.
> * A value, a line break, then {{/}}, then another value stays division. A 
> newline is not a left operand. {{9}} split across lines from {{3}} by {{/}} 
> still divides.
> * A closed {{/ab/}} is still a string. {{//}} and {{/*}} are still comments.
> {{$/}} is not treated as an unclosed string. {{$}} is an identifier, so 
> {{($/2)}}, {{$/=}}, and {{$//}} are division. An end-of-input alternative on 
> {{$/}} would reject those programs. An unclosed {{$/...}} therefore still 
> surfaces as a later error.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to