Skip to content

Commit

Permalink
Issue checkstyle#12507: Support record patterns preview
Browse files Browse the repository at this point in the history
  • Loading branch information
nrmancuso committed Dec 31, 2022
1 parent 05996a3 commit a0b9d39
Show file tree
Hide file tree
Showing 7 changed files with 1,427 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ arguments
pattern
: guardedPattern
| primaryPattern
| recordPattern
;

guardedPattern
Expand All @@ -889,14 +890,27 @@ primaryPattern
// Set of production rules below should mirror `pattern` production rule
// above. We do not reuse `pattern` production rule here to avoid a bunch
// of nested `PATTERN_DEF` nodes, as we also do for expressions.
(guardedPattern | primaryPattern)
(guardedPattern | primaryPattern | recordPattern )
RPAREN #parenPattern
| recordPattern #recordPatternDef
;

typePattern
: mods+=modifier* type=typeType[true] id
;

recordPattern
: type=typeType[true] recordStructurePattern id?
;

recordStructurePattern
: LPAREN recordComponentPatternList* RPAREN
;

recordComponentPatternList
: primaryPattern (COMMA primaryPattern)*
;

permittedSubclassesAndInterfaces
: LITERAL_PERMITS classOrInterfaceType[false] (COMMA classOrInterfaceType[false])*
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ public class JavaAstVisitorTest extends AbstractModuleTestSupport {
"visitClassType",
"visitClassOrInterfaceTypeExtended",
"visitQualifiedNameExtended",
"visitGuard"
"visitGuard",

// until https://github.com/checkstyle/checkstyle/issues/12507
"visitRecordComponentPatternList",
"visitRecordPatternDef",
"visitRecordPattern",
"visitRecordStructurePattern"
);

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,16 @@ public void testTrickyWhenUsage() throws Exception {
verifyAst(getNonCompilablePath("ExpectedJava19PatternsTrickyWhenUsage.txt"),
getNonCompilablePath("InputJava19PatternsTrickyWhenUsage.java"));
}

@Test
public void testRecordPatternsWithNestedDecomposition() throws Exception {
verifyAst(getPath("ExpectedRecordPatternsPreviewNestedDecomposition.txt"),
getNonCompilablePath("InputRecordPatternsPreviewNestedDecomposition.java"));
}

@Test
public void testRecordPatternsPreview() throws Exception {
verifyAst(getPath("ExpectedRecordPatternsPreview.txt"),
getNonCompilablePath("InputRecordPatternsPreview.java"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//non-compiled with javac: Compilable with Java19
package com.puppycrawl.tools.checkstyle.grammar.java19;

public class InputRecordPatternsPreview {
record Box<T>(T t) {
}

class A {
}

class B extends A {
}

sealed interface I permits C, D {
}

final class C implements I {
}

final class D implements I {
}

record Pair<T>(T x, T y) {
}

record Tuple(Object o1, Object o2, Object o3) {}
record VarArgs(Object... objArgs){}


static void test1(Box<Object> bo) {
if (bo instanceof Box<Object>(String s)) {
System.out.println("String " + s);
}
}

static void test2(Box<Object> bo) {
if (bo instanceof Box<?>(var s)) {
System.out.println("String " + s);
}
}

void test3(Box<I> bo) {
C c = new C();
if (bo instanceof Box<I>(var s)) {
System.out.println("String " + s);
}
else if (bo instanceof Box b) {

}
else if (bo instanceof Box<I> b && bo.t.equals(c)) {

}
else if (bo != null && bo.t.equals(c)) {

}
}

static void test4(Pair<I> p) {
if (p instanceof Pair<I>(C t1, C t2)) {
System.out.println(t2);
}
else if (p instanceof Pair<I>(D t1, D t2)) {
System.out.println(t1);
}
}

static void test5(Tuple t) {
if (t instanceof Tuple(String x, String y, String z)) {
System.out.println(x + y + z);
}
else if (t instanceof Tuple(Integer x, Integer y, Integer z)) {
System.out.println(x + y + z);
}
}

static void test5(VarArgs v) {
if (v instanceof VarArgs(Integer[] ints)) {
int l = ints.length;
}
else if (v instanceof VarArgs(Object[] objects)
&& objects.length > 2) {
int l = objects.length;
}
else if (v instanceof VarArgs(Object[] objects)
&& objects.length < 2){
int l = objects.length;
}

}

static void m1(Pair<I> p1) {
switch (p1) {
case Pair<I>(I i,C c) ->
System.out.println("C!");
case Pair<I>(I i,D d) ->
System.out.println("D!");
}

switch (p1) {
case Pair<I>(C c,I i) ->
System.out.println("T!");
case Pair<I>(D d,C c) ->
System.out.println("C!");
case Pair<I>(D d1,D d2) ->
System.out.println("D!");
}
}

String m2(Pair<I> p1) {
return switch (p1) {
case Pair<I>(C c,I i) -> "T!";
case Pair<I>(D d,C c) -> "C!";
case Pair<I>(D d1,D d2) -> "D!";
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//non-compiled with javac: Compilable with Java19
package com.puppycrawl.tools.checkstyle.grammar.java19;

public class InputRecordPatternsPreviewNestedDecomposition {
record A(Object o) {
}

record B(Object o) {
}

record Point(int x, int y) {
}

enum Color {RED, GREEN, BLUE}

record ColoredPoint(Point p, Color c) {
}

record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {
}

void method(Object param) {
switch (param) {
case A(Object o) -> {
}
case B(var o) -> {
}
default -> {
}
}
if (param instanceof A(var o)) {

}
}

// Decompose record
static void p1(Rectangle r) {
if (r instanceof Rectangle(ColoredPoint ul,ColoredPoint lr)) {
System.out.println(ul.c());
}
}

// We can decompose this record further, since Point is also
// a record
static void p2(Rectangle r) {
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);
}
}

// We can keep decomposing down to the last "inner" record
static void p3(Rectangle r) {
if (r instanceof Rectangle(ColoredPoint(Point p1,Color c1),
ColoredPoint lr1)
&& r instanceof Rectangle(
ColoredPoint(Point(int x,int y),Color c2),
ColoredPoint lr2)) {
System.out.println(r);
}
}

static void p4() {
int x1 = 0;
int x2 = 0;
int y1 = 0;
int y2 = 0;
Color c1 = Color.BLUE;
Color c2 = Color.GREEN;
Rectangle r = new Rectangle(new ColoredPoint(new Point(x1, y1), c1),
new ColoredPoint(new Point(x2, y2), c2));
if (r instanceof Rectangle(
ColoredPoint(Point(var x,var y),var c),
var lr)) {
System.out.println(x);
}
}
}

0 comments on commit a0b9d39

Please sign in to comment.