Skip to content

Support patterns in switch (preview-feature in Java 17) as described by JEP 406 #10848

@sviperll

Description

@sviperll

I have downloaded the latest cli from: https://checkstyle.org/cmdline.html#Download_and_Run
I have executed the cli and showed it below, as cli describes the problem better than 1,000 words

How it works Now:

$ java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment 21.9 (build 17+35)
OpenJDK 64-Bit Server VM 21.9 (build 17+35, mixed mode, sharing)

$ javac --version
javac 17

$ javac --release 17 --enable-preview Main.java
Note: Main.java uses preview features of Java SE 17.
Note: Recompile with -Xlint:preview for details.

$ cat config.xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
          "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
  <property name="severity" value="error"/>
  <property name="fileExtensions" value="java, properties, xml"/>
  <module name="TreeWalker">
    <module name="ConstantName"/>
  </module>
</module>

$ cat Main.java
package com.github.sviperll.checkstylejep406;

public class Main {
    public static void main(String[] args) {
        Object value = Integer.valueOf(42);
        String result = switch (value) {
            case null -> "It's null...";
            case String s -> "It's a string: " + s;
            case Integer i -> "It's an integer: " + i.toString();
            case Object v -> "It's something else: " + v.toString();
        };
        System.out.println(result);
    }
}

$ RUN_LOCALE="-Duser.language=en -Duser.country=US"
$ java $RUN_LOCALE -jar checkstyle-9.0.1-all.jar -c config.xml Main.java
Starting audit...
com.puppycrawl.tools.checkstyle.api.CheckstyleException: Exception was thrown while processing Main.java
	at com.puppycrawl.tools.checkstyle.Checker.processFiles(Checker.java:302)
	at com.puppycrawl.tools.checkstyle.Checker.process(Checker.java:221)
	at com.puppycrawl.tools.checkstyle.Main.runCheckstyle(Main.java:409)
	at com.puppycrawl.tools.checkstyle.Main.runCli(Main.java:332)
	at com.puppycrawl.tools.checkstyle.Main.execute(Main.java:191)
	at com.puppycrawl.tools.checkstyle.Main.main(Main.java:126)
Caused by: com.puppycrawl.tools.checkstyle.api.CheckstyleException: IllegalStateException occurred while parsing file /home/vir/code/checkstyle-jep406/Main.java.
	at com.puppycrawl.tools.checkstyle.JavaParser.parse(JavaParser.java:104)
	at com.puppycrawl.tools.checkstyle.TreeWalker.processFiltered(TreeWalker.java:152)
	at com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck.process(AbstractFileSetCheck.java:87)
	at com.puppycrawl.tools.checkstyle.Checker.processFile(Checker.java:328)
	at com.puppycrawl.tools.checkstyle.Checker.processFiles(Checker.java:289)
	... 5 more
Caused by: java.lang.IllegalStateException: 5:38: mismatched input '(' expecting ';'
	at com.puppycrawl.tools.checkstyle.JavaParser$CheckstyleErrorListener.syntaxError(JavaParser.java:251)
	at org.antlr.v4.runtime.ProxyErrorListener.syntaxError(ProxyErrorListener.java:41)
	at org.antlr.v4.runtime.Parser.notifyErrorListeners(Parser.java:544)
	at org.antlr.v4.runtime.DefaultErrorStrategy.reportInputMismatch(DefaultErrorStrategy.java:327)
	at org.antlr.v4.runtime.DefaultErrorStrategy.reportError(DefaultErrorStrategy.java:139)
	at com.puppycrawl.tools.checkstyle.CheckstyleParserErrorStrategy.recoverInline(CheckstyleParserErrorStrategy.java:38)
	at org.antlr.v4.runtime.Parser.match(Parser.java:206)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.blockStatement(JavaLanguageParser.java:6053)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.block(JavaLanguageParser.java:5968)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.methodBody(JavaLanguageParser.java:2858)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.methodDeclaration(JavaLanguageParser.java:2817)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.memberDeclaration(JavaLanguageParser.java:2665)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classBodyDeclaration(JavaLanguageParser.java:2592)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classBody(JavaLanguageParser.java:2403)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classDeclaration(JavaLanguageParser.java:1045)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.types(JavaLanguageParser.java:705)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.typeDeclaration(JavaLanguageParser.java:620)
	at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.compilationUnit(JavaLanguageParser.java:372)
	at com.puppycrawl.tools.checkstyle.JavaParser.parse(JavaParser.java:98)
	... 9 more
Caused by: org.antlr.v4.runtime.InputMismatchException
	... 23 more
Checkstyle ends with 1 errors.

Is your feature request related to a problem? Please describe.
The problem is that checkstyle crashes when there is a switch that uses pattern-matching

Describe the solution you'd like

Checkstyle should update Java-language grammer definition according to the grammar changes described in JEP 406

Relevant Java Language changes are drafted by Gavin Bierman to be amended to Java Language Specification in the future.

Here are some excerpts from the JEP:

We enhance switch statements and expressions in two ways:

  1. Extend case labels to include patterns in addition to constants, and
  2. Introduce two new kinds of patterns: guarded patterns and parenthesized patterns.

...

First, we introduce a new null label for a case, which clearly matches when the value of the selector expression is null.

...

Consequently, the previous example suggests that we should support a case null, String s -> label.

...

(The reverse form, case String s, null should also be allowed and behave identically.)

...

To do so we introduce a new default case label:
case null, default ->

...

More precisely, we change the grammar of patterns.
Assuming that the record patterns and array patterns of JEP 405 are added, the grammar for patterns will become:

    Pattern:
      PrimaryPattern
      GuardedPattern

    GuardedPattern:
      PrimaryPattern && ConditionalAndExpression

    PrimaryPattern:
      TypePattern
      ( Pattern )

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions