Skip to content
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

Issue #12507: Support record patterns preview #12516

Merged
merged 1 commit into from
May 14, 2023

Conversation

nrmancuso
Copy link
Member

@nrmancuso nrmancuso commented Dec 10, 2022

closes #12507

We extend the Java programming language with nestable record patterns.

The grammar for patterns will become:

Pattern:
  TypePattern
  ParenthesizedPattern
  RecordPattern

TypePattern:
  LocalVariableDeclaration

ParenthesizedPattern:
  ( Pattern )

RecordPattern:
  ReferenceType RecordStructurePattern [ Identifier ]

RecordStructurePattern:
  ( [ RecordComponentPatternList ] )

RecordComponentPatternList : 
  Pattern { , Pattern }

Compact view of AST: https://github.com/checkstyle/checkstyle/wiki/Record-Pattern-Preview---AST-strucuture


Reports

Check regression reports:
https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part1-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part4-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part5-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/sevntu-check-regression_part_2-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part2-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part6-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/part3-report/index.html

https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/sevntu-check-regression_part_1-report/index.html

No differences in check behavior ^

ANTLR regression report:
https://nrmancuso.github.io/reports/issue-12507/2023-04-21-T-13-58-36/antlr-report/index.html

Only change is in exception line number in non-compilable files ^

@nrmancuso nrmancuso self-assigned this Dec 10, 2022
@nrmancuso nrmancuso force-pushed the issue-12507 branch 3 times, most recently from bdc5d58 to 9e53eda Compare December 10, 2022 16:45
@nrmancuso

This comment was marked as outdated.

@nrmancuso
Copy link
Member Author

nrmancuso commented Dec 31, 2022

Notes to self:

  • Need to add more inputs with while/do while/for loops with record pattern decomp
  • nested decomp in loops

Example:

        if (param instanceof A(var o)) {
            System.out.println(o);
        }

        while (param instanceof A(var o)) {
            System.out.println((String)o);
        }

        for (; param instanceof A(var o);) {
            System.out.println((String)o);
        }

@nrmancuso
Copy link
Member Author

nrmancuso commented Dec 31, 2022

@romani @rnveach @pbludov @strkkk please take a look at latest commit (3dc7ed7) and let's discuss new tokens/ AST structure.

@nrmancuso
Copy link
Member Author

nrmancuso commented Jan 11, 2023

please take a look at latest commit (3dc7ed7) and let's discuss new tokens/ AST structure.

@rnveach @romani ping

@rnveach
Copy link
Member

rnveach commented Jan 11, 2023

@nrmancuso Do you have a link to the JLS that your changes cover?

@nrmancuso
Copy link
Member Author

@nrmancuso Do you have a link to the JLS that your changes cover?

No, since this is a preview feature, the only specification is in the JEP.

@rnveach
Copy link
Member

rnveach commented Jan 11, 2023

please take a look at latest commit (3dc7ed7) and let's discuss new tokens/ AST structure.

The only thing I noticed to bring up is I question the need for RECORD_PATTERN_COMPONENTS when it only has 1 child. COMPONENTS to me make it sounds like multiples, but I didn't find any with multiple. Maybe I am just missing it.

| | | | | | | |--TYPE -> TYPE [46:35]
| | | | | | | | `--IDENT -> ColoredPoint [46:35]
| | | | | | | |--LPAREN -> ( [46:47]
| | | | | | | |--RECORD_PATTERN_COMPONENTS -> RECORD_PATTERN_COMPONENTS [46:48]
Copy link
Member Author

Choose a reason for hiding this comment

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

@rnveach example of multiple components

Copy link
Member

Choose a reason for hiding this comment

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

Thanks I figured I was missing it. That was my only real concern. I feel fine with what you are doing.

@nrmancuso
Copy link
Member Author

please take a look at latest commit (3dc7ed7) and let's discuss new tokens/ AST structure.

@romani ping

| | `--IDENT -> r [45:29]
| |--RPAREN -> ) [45:30]
| `--SLIST -> { [45:32]
| |--LITERAL_IF -> if [46:8]
Copy link
Member Author

@nrmancuso nrmancuso Mar 18, 2023

Choose a reason for hiding this comment

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

This is the beginning of a complicated case of record pattern decomposition:

        if (r instanceof Rectangle(ColoredPoint(Point p1,Color c1),
                ColoredPoint lr1)
                && r instanceof Rectangle(ColoredPoint(Point p2,Color c2),
                ColoredPoint lr2) && lr2.c == Color.BLUE) {
            System.out.println(r);
        }

Copy link
Member

Choose a reason for hiding this comment

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

| | | | `--IDENT -> b [13:23]
| | | |--RPAREN -> ) [13:24]
| | | |--LCURLY -> { [13:26]
| | | |--SWITCH_RULE -> SWITCH_RULE [14:12]
Copy link
Member Author

@nrmancuso nrmancuso Mar 18, 2023

Choose a reason for hiding this comment

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

Start of another nested record decomposition, with when usage:

            case Box<Box<String>>(Box<String>(String s)box)
                    when (("test".equals(s) && box.x != 7))  -> 1;


@nrmancuso
Copy link
Member Author

nrmancuso commented Mar 18, 2023

@romani left some comments, but basically we are only adding record patterns to existing pattern grammar. It is a tricky syntax for parsing, which is why I have all the crazy inputs. But - from a reviewing perspective a great deal of the input here very similar.

@nrmancuso
Copy link
Member Author

nrmancuso commented Mar 19, 2023

Also, To help others to understand what is happening with record decomposition:

if (b instanceof Box<String>(String s)) is similar to if (b instanceof String s); the record component pattern allows us to declare and use a pattern variable that is a record component of the record that is in the record pattern. Consider:

➜  src javac --enable-preview -source 19 Test.java
Note: Test.java uses preview features of Java SE 19.
Note: Recompile with -Xlint:preview for details.
➜  src cat Test.java 
class Test<T> {
    record Box<T>(T t) {}

    // example of nested record decomposition with pattern
    // variable declaration from nested record
    T m1(Box<Box<T>> b) {
        // this declaration is equaivlent to the following decomposition
        // in 'if' statement
        final Box<Box<String>> nestedRecordBox =
                new Box<>(new Box<>("some string"));

        if (b instanceof Box<Box<T>>( // <- 'outer' record is decomposed
                Box<T>( // <- 'inner' record is decomposed
                        String s // <- pattern variable is declared
                        ))) {
            // pattern variable s is in scope
            System.out.println(s);
        }
        return null;
    }

    // example of record decomposition with pattern variable declaration
    T m2(Box<T> b) {
        // this declaration is equaivlent to the following decomposition
        // in 'if' statement
        final Box<String> recordBox = new Box<>("some string");

        if (b instanceof Box<T>( // <- record is decomposed
                String s // <- pattern variable is declared
                )) {
            // pattern variable s is in scope
            System.out.println(s);
        }
        return null;
    }

    // example of a pattern variable declaration
    void m3(Object o) {
        // this declaration is equaivlent to the following pattern variable
        // declaration in 'if' statement
        final String str = "some string";

        if (o instanceof String s // <- pattern variable is declared
            ) {
            // pattern variable s is in scope
            System.out.println(s);
        }
    }
}

Of course, I made the actual input files terrible to make sure we can parse all such code, but basically all the inputs are variations on the above.

Copy link
Member

@romani romani left a comment

Choose a reason for hiding this comment

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

items:

Copy link
Member

@romani romani left a comment

Choose a reason for hiding this comment

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

I see no problems with AST, all good.
https://github.com/checkstyle/checkstyle/wiki/Record-Pattern-Preview---AST-strucuture
I think we can finalize this PR.

config/projects-to-test/openjdk19-excluded.files

jdk19 to no-execution to make sure we can parse all record patterns that openjdk have in its test inputs - GOOD.

items:

Copy link
Member

@romani romani left a comment

Choose a reason for hiding this comment

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

Last minor:

@nrmancuso nrmancuso force-pushed the issue-12507 branch 2 times, most recently from 0bd3eab to 28515c4 Compare May 10, 2023 05:14
Copy link
Member

@romani romani left a comment

Choose a reason for hiding this comment

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

Ok to merge

@romani romani assigned rnveach and unassigned romani May 11, 2023
@rnveach rnveach merged commit f5bed1f into checkstyle:master May 14, 2023
109 checks passed
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.

Support record patterns (preview-feature in Java 19) as described by JEP 405
3 participants