Skip to content

Try to fix yield with expression containing dots#3361

Closed
koppor wants to merge 5 commits into
javaparser:masterfrom
koppor:yield-issue
Closed

Try to fix yield with expression containing dots#3361
koppor wants to merge 5 commits into
javaparser:masterfrom
koppor:yield-issue

Conversation

@koppor

@koppor koppor commented Sep 2, 2021

Copy link
Copy Markdown
Contributor

Details at #3364.

This PR adds a test case for the case that after yield a method is called. Example: yield Collections.emptyList().

        List<Integer> result = switch (s) {
            case "Foo":
                yield List.of(1);
            case "Bar":
                yield List.of(2);
            default:
                System.out.println("Neither Foo nor Bar, hmmm...");
                yield Collections.emptyList();
        };

Error:

org.opentest4j.AssertionFailedError: [(line 3,col 15) Parse error. Found ".", expected one of  "," ";" "=" "@" "["

Expected: No error

@koppor koppor changed the title Add test for yield with expression containing dots Try to fix yield with expression containing dots Sep 2, 2021
@koppor

koppor commented Sep 2, 2021

Copy link
Copy Markdown
Contributor Author

On the CI, I get following error:

ParseErrorRecoveryTest.labeledStatementSemicolonRecovery:62 » IllegalState ???...

In IntelliJ, this test is green. Locally, with ./mvnw, I also get this error. Not sure, how to proceed.

Longer error:

>
[ERROR]   JavaRecordNameTest.recordIsAValidVariableName:32 [(line 1,col 8) 'record' cannot be used as an identifier as it is a keyword.]
[ERROR]   TransformationsTest.exampleParam5:169->AbstractLexicalPreservingTest.assertTransformed:79  -- failed due to line separator differ

ences -- Expected: \n, but actual:  (system eol: \r\n) ==> expected: <// This is my class, with my comment
class A {
    int foo(int p1, char p2) {
        return p1;
    }
}> but was: <// This is my class, with my comment
class A {
    int foo(int p1, char p2) {
        return p1;
    }
}>
[ERROR] Errors:
[ERROR]   ParseErrorRecoveryTest.labeledStatementSemicolonRecovery:62 ; IllegalState ???...

@jlerbsc

jlerbsc commented Sep 2, 2021

Copy link
Copy Markdown
Collaborator

Hi @koppor you have to use TestUtils.assertEqualsStringIgnoringEol to compare 2 string without the test being sensitive at the end of the line.

@koppor koppor mentioned this pull request Sep 2, 2021
5 tasks
@koppor

koppor commented Sep 2, 2021

Copy link
Copy Markdown
Contributor Author

I added the string comparison.

The other error still is there - maybe my grammar "fix" messed up some special case. Currently, I have no clue how to continue here.

 [INFO] Running com.github.javaparser.ParseErrorRecoveryTest
Error:  Tests run: 7, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.05 s <<< FAILURE! - in com.github.javaparser.ParseErrorRecoveryTest
Error:  com.github.javaparser.ParseErrorRecoveryTest.testBodyRecoverLevel  Time elapsed: 0.003 s
Error:  com.github.javaparser.ParseErrorRecoveryTest.labeledStatementSemicolonRecovery  Time elapsed: 0.006 s  <<< ERROR!
java.lang.IllegalStateException: ???; is not LabeledStmt, it is UnparsableStmt
	at com.github.javaparser.ParseErrorRecoveryTest.labeledStatementSemicolonRecovery(ParseErrorRecoveryTest.java:62)


// Note that we explicitly care about line endings when handling lexical preservation.
assertEqualsString(expectedCode, actualCode);
TestUtils.assertEqualsStringIgnoringEol(expectedCode, actualCode);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You are changing behavior that is intentional!

Note that we explicitly care about line endings when handling lexical preservation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Then I did not get your comment #3361 (comment) right. Reverted bbfc0d7.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Apologies, without context (note the comment on line 79) it wasn't obvious from the quoted errors that this was a place where line endings were important.

@koppor

koppor commented Sep 4, 2021

Copy link
Copy Markdown
Contributor Author

I updated the PR to contain two commits:

  1. Add test case for valid Java Code: 4a0123f (#3361)
  2. Naive try to fix the issue: 693079d (#3361)

@koppor koppor marked this pull request as draft September 4, 2021 07:01
@jlerbsc

jlerbsc commented Mar 18, 2022

Copy link
Copy Markdown
Collaborator

@MysterAitch The PR goal was to fix a grammar issue. Can you approve the @koppor 's proposal?

MethodCallExpr methodCallExpr = (MethodCallExpr) yieldStmt.getExpression();
IntegerLiteralExpr firstArgument = (IntegerLiteralExpr) methodCallExpr.getArguments().get(0);
assertEquals(1, firstArgument.asNumber());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmmm, these ought to go to YieldStmtTest

@matozoid

Copy link
Copy Markdown
Contributor

I find it weird that the BlockStatement grammar has to be changed for this - it has been fine for years. Can you explain the fix, @koppor ?

@MysterAitch

Copy link
Copy Markdown
Member

I find it weird that the BlockStatement grammar has to be changed for this - it has been fine for years. Can you explain the fix, @koppor ?

Within a SwitchEntry, the element to the right of a colon is one-or-more BlockStatement.

I am still investigating, but it appears that our definition of a BlockStatement isn't wholly correct per #3364 whereby the Yield.of(1) is first being interpreted/parsed as a VariableDeclaration before being considered as a Statement -- hence (I presume) the change in order/precedence suggested within @koppor 's PR.

Consider the following grammar entries from the JLS:

SwitchBlockStatementGroup:
    SwitchLabel : {SwitchLabel :} BlockStatements 
BlockStatements:
    BlockStatement {BlockStatement}
BlockStatement:
    LocalVariableDeclarationStatement
    ClassDeclaration
    Statement
Statement:
    StatementWithoutTrailingSubstatement
    LabeledStatement
    IfThenStatement
    IfThenElseStatement
    WhileStatement
    ForStatement
StatementNoShortIf:
    StatementWithoutTrailingSubstatement
    LabeledStatementNoShortIf
    IfThenElseStatementNoShortIf
    WhileStatementNoShortIf
    ForStatementNoShortIf
StatementWithoutTrailingSubstatement:
    Block
    EmptyStatement
    ExpressionStatement
    AssertStatement
    SwitchStatement
    DoStatement
    BreakStatement
    ContinueStatement
    ReturnStatement
    SynchronizedStatement
    ThrowStatement
    TryStatement
    YieldStatement

@MysterAitch

Copy link
Copy Markdown
Member

The PR appears to fix the yield problem, but breaks the error recovery code (multiple tests no longer pass).

@matozoid -- Perhaps you are able to advise on this, please?

@matozoid

Copy link
Copy Markdown
Contributor

What's the error recovery problem you see, @MysterAitch ?

@koppor

koppor commented Jun 6, 2022

Copy link
Copy Markdown
Contributor Author

I find it weird that the BlockStatement grammar has to be changed for this - it has been fine for years. Can you explain the fix, @koppor ?

I was trying to use the LOOKAHEAD feature to ensure that yield is properly captured. However, it does not work.

Maybe, the added test cases are useful for a "proper" fix?

@jlerbsc

jlerbsc commented Oct 27, 2022

Copy link
Copy Markdown
Collaborator

This PR is closed because JavaParser 3.24.7 correctly parse yield statement.

@jlerbsc jlerbsc closed this Oct 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants