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

Create new check IllegalIdentifierName #8764

Closed
nrmancuso opened this issue Aug 26, 2020 · 7 comments · Fixed by #8766
Closed

Create new check IllegalIdentifierName #8764

nrmancuso opened this issue Aug 26, 2020 · 7 comments · Fixed by #8766

Comments

@nrmancuso
Copy link
Member

From #8308

Adding new keywords to a language is very difficult, since they are probably used as identifiers in the existing code. Our parser should accept such keyword as an identifier, but we need a new check. Something like AvoidUsingKeywordsAsIdentifiers.

Originally posted by @pbludov in #8267 (comment)

From https://jaxenter.com/java-14-records-deep-dive-169879.html:

"However, you should refrain from using record as an identifier because it could be included as a keyword in a future Java version."

Java already issues the following errors:

$ cat TestClass.java 
public class record {
}
public class var {
}

$ /usr/lib/jvm/java-14-openjdk-amd64/bin/javac --enable-preview --source 14 TestClass.java 
TestClass.java:1: error: 'record' not allowed here
public class record {
             ^
  as of release 13, 'record' is a restricted type name and cannot be used for type declarations
TestClass.java:5: error: 'var' not allowed here
public class var {
             ^
  as of release 10, 'var' is a restricted type name and cannot be used for type declarations
2 errors

So, the addition of this new check would help remind developers that it is bad practice to use context-sensitive/ restricted keywords as identifiers; this will help to make code more future-proof and easy to read. I would expect the following:

➜  src /usr/lib/jvm/java-14-openjdk/bin/javac --enable-preview --source 14 TestClass.java
Note: TestClass.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
➜  src cat TestClass.java
public class TestClass {
    public static void main(String... args) {
        var var = 4; // violation, "var" should not be used as an identifier.

        int record = 15; // violation, "record" should not be used as an identifier.

        String yield = "yield"; // violation, "yield" should not be used as an identifier.

        record Record // violation, "Record" should not be used as an idenitifier.
                (Record record) { // violation, "record" should not be used as an identifier.
        }
    }
}


@romani
Copy link
Member

romani commented Aug 26, 2020

Can itbe done by https://checkstyle.org/config_naming.html#LocalVariableName by more advanced regexp ?

@nrmancuso
Copy link
Member Author

➜  src /usr/lib/jvm/java-14-openjdk/bin/javac --enable-preview --source 14 TestClass.java                               
Note: TestClass.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
➜  src cat config.xml                                                                                                   
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
        "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
    <property name="charset" value="UTF-8"/>
    <module name="TreeWalker">
        <module name="LocalVariableName">
            <property name="format" value="(?i)^(?!(record|yield|var)$).+$"/>
        </module>
        <module name="TypeName">
            <property name="format" value="(?i)^(?!(record|yield|var)$).+$"/>
        </module>
    </module>
</module>%                                                                                                                     ➜  src cat TestClass.java                                                                                               
public class TestClass {
    public static void main(String... args) {
        var var = 4; // violation, "var" should not be used as an identifier.

        int record = 15; // violation, "record" should not be used as an identifier.

        String yield = "yield"; // violation, "yield" should not be used as an identifier.

        record Record // violation, "Record" should not be used as an idenitifier.
                (Record record) { // should be violation, "record" should not be used as an identifier.
        }

        String yieldString = "yieldString"; // ok, part of another word
        record MyRecord(){} // ok, part of another word
        var variable = 2; // ok, part of another word
    }
}
➜  src java -jar /home/nick/IdeaProjects/checkstyle/target/checkstyle-8.36-SNAPSHOT-all.jar -c config.xml TestClass.java\

Starting audit...
[ERROR] /home/nick/Desktop/full-record-grammar/check-updates/src/TestClass.java:3:13: Name 'var' must match pattern '(?i)^(?!(record|yield|var)$).+$'. [LocalVariableName]
[ERROR] /home/nick/Desktop/full-record-grammar/check-updates/src/TestClass.java:5:13: Name 'record' must match pattern '(?i)^(?!(record|yield|var)$).+$'. [LocalVariableName]
[ERROR] /home/nick/Desktop/full-record-grammar/check-updates/src/TestClass.java:7:16: Name 'yield' must match pattern '(?i)^(?!(record|yield|var)$).+$'. [LocalVariableName]
[ERROR] /home/nick/Desktop/full-record-grammar/check-updates/src/TestClass.java:9:16: Name 'Record' must match pattern '(?i)^(?!(record|yield|var)$).+$'. [TypeName]
Audit done.
Checkstyle ends with 4 errors.

@nrmancuso
Copy link
Member Author

nrmancuso commented Aug 27, 2020

(Record record) { // should be violation, "record" should not be used as an identifier.

Do we need another new check, RecordComponentName?

We have LambdaParameterName, MemberName, and ParameterName. Since record components are basically "members", we should make it possible for users to enforce naming conventions on them.

@nrmancuso nrmancuso changed the title New Check: AvoidUsingKeywordsAsIdentifiers New Check: IllegalIdentifierName Aug 27, 2020
@pbludov
Copy link
Member

pbludov commented Aug 27, 2020

The list of keywords may expand when a new version of Java is released.
How should this check change when a new version is released? We can add new keywords to the default list, but this will affect existing users of this check (this is normal for the verbosity level WARNING). Or we can add the java-release property (latest by default). With an additional user-provided stop list in a separate property.

@romani
Copy link
Member

romani commented Aug 27, 2020

Do we need another new check, RecordComponentName?

Yes, existing
https://checkstyle.org/config_naming.html#MemberName
Does not match , there are a lot of unrelated properties.
Please create issue on it.

@romani
Copy link
Member

romani commented Aug 27, 2020

How should this check change when a new version is released?

We update default.
If new keyword is introduced, it do mean that one day it will be at LtS release and stay forever. So user should be prepared for this in advance. If he doesn't not want it, he just override default value. I do not think that extra property will contribute good to this. User just need to adjust regexp.
Regexp is more flexible and users can go crazy like forbidding "slave|master" to be in names :) .

nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
@nrmancuso nrmancuso changed the title New Check: IllegalIdentifierName Create new check IllegalIdentifierName Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
@romani romani added this to To do in Java 14 syntax features via automation Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 27, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 28, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 28, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 28, 2020
nrmancuso added a commit to nrmancuso/checkstyle that referenced this issue Aug 28, 2020
@pbludov pbludov added this to the 8.36 milestone Aug 28, 2020
@pbludov pbludov linked a pull request Aug 28, 2020 that will close this issue
@pbludov
Copy link
Member

pbludov commented Aug 28, 2020

Fix is merged.

@pbludov pbludov closed this as completed Aug 28, 2020
Java 14 syntax features automation moved this from To do to Done Aug 28, 2020
shiliyu pushed a commit to shiliyu/checkstyle that referenced this issue Sep 1, 2020
shiliyu pushed a commit to shiliyu/checkstyle that referenced this issue Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

3 participants