alibaba / p3c

Alibaba Java Coding Guidelines pmd implements and IDE plugin
https://github.com/alibaba/p3c/wiki
Apache License 2.0
30.49k stars 8.07k forks source link

How to add a new rule #986

Open Rapter1990 opened 1 year ago

Rapter1990 commented 1 year ago

I tried to use your plugin in my Intellij IDEA 2023.2.1 Ultimate Edition and it feels very comfortable to analyze the code and suggest some major and minor ideas which help you revise the code.

What I just want to ask is to learn how to add a new rule in the plugin.

Which documentation do I follow that? Can you guide me?

I hope you can help me.

I'm waiting for response as early as possible.

godfather1103 commented 1 year ago
  1. Add a class, extends AbstractAliRule
  2. add rule to idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml
  3. repackage plugin
Rapter1990 commented 1 year ago

@godfather1103 Do you have any documentation or tutorial to add a rule?

If you have, can you share it with me?

godfather1103 commented 1 year ago

https://docs.pmd-code.org/latest/pmd_userdocs_extending_writing_java_rules.html

Rapter1990 commented 1 year ago

@godfather1103 Thank you for your sharing the resource with me.

Rapter1990 commented 1 year ago

@godfather1103 I want to add a sample rule but I have no idea to add it. I looked through the documentation but I couldn't find detail information about it. Do you have any video record or sample tutorial for it like build the rule from scratch. I hope you can help me. I'm waiting for your response as soon as possible.

godfather1103 commented 1 year ago

https://docs.pmd-code.org/latest/pmd_userdocs_extending_your_first_rule.html#rule-development-process https://docs.pmd-code.org/latest/pmd_userdocs_extending_writing_rules_intro.html

godfather1103 commented 1 year ago

I don't have any experience writing rules independently, I just modified bugs in existing rules

godfather1103 commented 1 year ago

P3C pmd is based on pmd, so you may need to search for a tutorial on writing pmd rules

Rapter1990 commented 1 year ago

@godfather1103 What I just want to ask is to learn if I can add a rule (after I've learnt) to the plugin. Is it possible to do that. Let me know.

godfather1103 commented 1 year ago
  1. git clone https://github.com/godfather1103/p3c.git
  2. import idea-plugin project,this is a gradle project
  3. create class extends AbstractAliRule in idea-plugin/p3c-common module,write rule
  4. add rule to idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml
  5. repackage plugin
godfather1103 commented 1 year ago

this is way to add custom rule for plugin

Rapter1990 commented 1 year ago

@godfather1103

2 ) Do I define the rule this location Link . Is it right?

3 ) Create class class extends AbstractAliRule in Link

4 ) How can I ad the rule as there are some xml files Link

5 ) Do I run this command mvn clean package spring-boot:repackage.

Who can I connect with someone whose experience is enough to define a new ?

I hope you can help me.

godfather1103 commented 1 year ago

2-4 is right 5 is gradle clean :p3c-idea:buildPlugin or ./gradlew clean :p3c-idea:buildPlugin

Rapter1990 commented 1 year ago

@godfather1103 What about 3 and my last question?

Rapter1990 commented 1 year ago

@godfather1103 I hope you can provide a video tutorial for adding a new rule to this plugin like building from scratch.

godfather1103 commented 1 year ago

I don't have any relevant tutorials, I hope others can provide them in the future.

godfather1103 commented 1 year ago

Are you a beginner? Do you have any experience in Java development?

godfather1103 commented 1 year ago

My English is not good and I need to rely on translation software, so I don't quite understand your needs. Do you want to know how to write PMD rules? Do you want to know how to add pmd rules to this IDEA plugin?

Rapter1990 commented 1 year ago

@godfather1103 I already had an experience in Java Development. You can look through my github profile. As I couldn't find any relevant tutorials like building to add a rule from scratch, I asked you about it. I hope other contributors can help me provide them. Is it possible to connect with them about it. Except for that, yeah, you're right. I want to know how to write PMD rules and add pmd rules to this IDEA plugin.

godfather1103 commented 1 year ago

If I have time on the weekend, I can try writing a document titled 'How to Add a Simple Custom Rule', hoping it will be helpful to you.

Rapter1990 commented 1 year ago

@godfather1103 I hope you can do it. Is it possible to record a video like build from scratch? That's why I can easily get how to add a custom rule like detecting deprecated methods, greater or equal to or vice versa. I'm waiting for your feedback as soon as possible.

Rapter1990 commented 1 year ago

@godfather1103 Hi, you forgot to share a video like "building a custom rule in the plugin and then using it from scratch". I hope you can prepare it as soon as possible.

godfather1103 commented 1 year ago

@Rapter1990 Sorry, due to the approaching holiday, I am working overtime to process work and currently do not have time to record videos.

godfather1103 commented 1 year ago

@Rapter1990 I recorded a video explaining how to add custom rules. After the video website review, I will attach the corresponding link.

godfather1103 commented 1 year ago

The language in the video is Chinese, and you can check the demo branch for the specific code

godfather1103 commented 1 year ago

this is video https://www.bilibili.com/video/BV1uN411E7TE/

godfather1103 commented 1 year ago

example code https://github.com/godfather1103/p3c/commit/f7efc02e7649212a4965f186fd8be14e3528b144

godfather1103 commented 1 year ago

https://github.com/godfather1103/p3c/wiki/quick-start

Rapter1990 commented 1 year ago

@godfather1103 Thank you for your sharing video and documentation but the video cannot be enough clear to see even if I revised its settings. Can you reupload it with high resolution if you don't mind?

godfather1103 commented 1 year ago

@godfather1103 Thank you for your sharing video and documentation but the video cannot be enough clear to see even if I revised its settings. Can you reupload it with high resolution if you don't mind?

I'm on vacation recently. I'll give it a try tomorrow evening

godfather1103 commented 1 year ago

@godfather1103 Thank you for your sharing video and documentation but the video cannot be enough clear to see even if I revised its settings. Can you reupload it with high resolution if you don't mind?

Has the video resolution been switched to 720p?

godfather1103 commented 1 year ago

OBS recorded videos can only reach 720p. If the 720p video still looks blurry, I will try to modify the font size of IDEA.

Rapter1990 commented 1 year ago

@godfather1103 As I cannot register the website, I cannot see the video in 720p. Can you share the 720 video by email? I already defined my email address in my README.md

Rapter1990 commented 1 year ago

@godfather1103 Can you share the video by email with me as it cannot be clear to see?

Rapter1990 commented 1 year ago

@godfather1103 Hi, Can you share the video if possible?

godfather1103 commented 1 year ago

Expected to be sent before 23:00 Beijing time

JackChu

@.*** |

Rapter1990 commented 1 year ago

@godfather1103 I'll wait for your email.

godfather1103 commented 1 year ago

The email has been sent. Because the original video was on another computer, I downloaded a 720p video from Bilibili.

godfather1103 commented 1 year ago

example code godfather1103/p3c@f7efc02

The code in the video can be seen from this commit

Rapter1990 commented 1 year ago

@godfather1103 I also want to add a sample custom rule like methods written in camelCase and add it into plugin. Next, I can use it. Can you add me as a contributor in this repo? Can you help me how to define it? Can you direct me?

godfather1103 commented 1 year ago

@Rapter1990 https://github.com/alibaba/p3c? Sorry,I am not the owner of this repo. I don't have the relevant permissions.

Rapter1990 commented 1 year ago

@godfather1103 Hi. I tried to download the repo as a zip file and added a sample custom rule. I have a problem when I run gradle clean :p3c-idea:buildPlugin under idea-plugin.

p3c-master\idea-plugin> gradle clean :p3c-idea:buildPlugin

Here is the error.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'idea-plugin'.
> Could not resolve all dependencies for configuration ':classpath'.
   > Using insecure protocols with repositories, without explicit opt-in, is unsupported.

> For more information, please refer to https://docs.gradle.org/8.3/dsl/org.gradle.api.artifacts.repositories.UrlArtifactRepository.html#org.gradle.api.artifacts.repositories.U
rlArtifactRepository:allowInsecureProtocol in the Gradle documentation.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 1s
Rapter1990 commented 1 year ago

@godfather1103 I defined allowInsecureProtocol = true to build.gradle of idea plugin shown below

buildscript {
    repositories {
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots/"
        }
        maven {
            url 'http://dl.bintray.com/jetbrains/intellij-plugin-service'
            allowInsecureProtocol = true
        }
        mavenCentral()

    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

Then I run this command gradle clean :p3c-idea:buildPlugin --warning-mode all , I got this issue shown below

PS C:\Users\User\IdeaProjects\p3c-master\idea-plugin> gradle clean :p3c-idea:buildPlugin --warning-mode all
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

> Configure project :
The org.gradle.util.WrapUtil type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs.gradle.o
rg/8.3/userguide/upgrading_version_7.html#org_gradle_util_reports_deprecations
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The Project.getConvention() method has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs.gradle.
org/8.3/userguide/upgrading_version_8.html#deprecated_access_to_conventions
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The org.gradle.api.plugins.Convention type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs
.gradle.org/8.3/userguide/upgrading_version_8.html#deprecated_access_to_conventions
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The org.gradle.api.plugins.JavaPluginConvention type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: ht
tps://docs.gradle.org/8.3/userguide/upgrading_version_8.html#java_convention_deprecation
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.
-----------
* Where:
Build file 'C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle' line: 21

* What went wrong:
A problem occurred evaluating root project 'idea-plugin'.
> 'void org.gradle.api.artifacts.dsl.DependencyHandler.registerTransform(org.gradle.api.Action)'

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
A problem occurred configuring root project 'idea-plugin'.
> Could not create task ':compileKotlin'.
   > Cannot use @TaskAction annotation on method AbstractKotlinCompile.execute() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid paramet
er to an action method.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
==============================================================================

BUILD FAILED in 11s

How can I fix it? I use gradle 8.3

godfather1103 commented 1 year ago

https://github.com/godfather1103/p3c.git

Download code from this repository.

There is an issue with the build script in alibaba/p3c.

JackChu

@.*** |

Rapter1990 commented 1 year ago

@godfather1103 I downloaded your repository and tested it. I got the same issue which I mentioned before. How can I fix it? As I mentioned before, I use gradle 8.3

Rapter1990 commented 1 year ago

@godfather1103 I fixed it but there is another question to you. I saw idea_version=2018.3 in gradle.properties of idea-plugin. How can I use this plugin in 2023.2.2?

Here is the error shown below

* What went wrong:
A problem occurred configuring project ':p3c-idea'.
> Cannot find builtin plugin git4idea for IDE: C:\Users\User\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2023.2.2\9501eca11251de344f61d01388781a8
fabcd81df\ideaIC-2023.2.2
godfather1103 commented 1 year ago
  1. my project base on gradle 7.5.1 Try gradle7.5.1, or use godfather1103/p3c idea-plugin/gradlew

  2. my project idea_version=2023.2, support 2023.2-2023.2.* idea-plugin/p3c-idea/build.gradle.kts

    tasks {
    patchPluginXml {
        sinceBuild.set("${yearVersion}${noVersion}.0")
        untilBuild.set("${yearVersion}${noVersion}.*")
    }
godfather1103 commented 1 year ago

branch before-2022.3,supports versions up to and including 2022.3

godfather1103 commented 1 year ago

idea-plugin/build.gradle.kts

val ideaVersion = property("idea_version") as String

val yearVersion = ideaVersion
    .split(".")
    .first()
    .substring(2)
    .toInt()

val noVersion = ideaVersion
    .substring(ideaVersion.indexOf(".") + 1)
    .toInt()

val myPlugins = when (yearVersion) {
    in 23..Int.MAX_VALUE -> setOf("vcs-git", "java")
    22 -> if (noVersion == 3) setOf("vcs-git", "java") else setOf("git4idea", "java")
    in 19..21 -> setOf("git4idea", "java")
    else -> setOf("git4idea")
}

ext["ideaVersion"] = ideaVersion
ext["yearVersion"] = yearVersion
ext["noVersion"] = noVersion
ext["myPlugins"] = myPlugins
Rapter1990 commented 1 year ago

@godfather1103 After adding a sample rule to check the method is camelcase of not, I tried to build the repo with gradle clean :p3c-idea:buildPlugin in idea_version=2018.3 but my rule cannot be detected. How can I fix it?

Here are the code snippets shown below

p3c-pmd/src/main/resources/messages.xml

<!-- CAMEL CASE RULE  -->
    <entry key="demo.CamelCaseMethodNameRule.violation.msg">
        <![CDATA[方法名称应采用驼峰命名法。]]>
    </entry>

p3c-pmd/src/main/resources/messages-en.xml

<!-- CAMEL CASE RULE -->
    <entry key="demo.CamelCaseMethodNameRule.violation.msg">
        <![CDATA[Method names should be in camelCase.]]>
    </entry>

p3c-pmd/src/test/java/demo/CamelCaseMethodNameRuleTest

public class CamelCaseMethodNameRuleTest extends SimpleAggregatorTst {
    @Override
    protected void setUp() {
        addRule("rulesets/java/demo.xml", "CamelCaseMethodNameRule");
    }
}

p3c-pmd/src/test/resources/rulesets/java/demo.xml

<?xml version="1.0"?>

<ruleset name="AlibabaJavaOthers" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>Demo</description>
    <rule name="CamelCaseMethodNameRule"
          language="java"
          message="demo.CamelCaseMethodNameRule.violation.msg"
          class="demo.CamelCaseMethodNameRule">
        <priority>5</priority>
    </rule>
</ruleset>

p3c-pmd/src/test/resources/demo/xml/CamelCaseMethodNameRule.xml

<?xml version="1.0" encoding="UTF-8"?>
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_0_0.xsd">
    <code-fragment id="camelCaseMethodName">
        <![CDATA[
        public class Example {

            public int NonCamelCaseMethod() {
                return 0;
            }

            public int camelCaseMethod() {
                return 1;
            }
        }
        ]]>
    </code-fragment>
    <test-code>
        <description>Method names are in camelCase</description>
        <expected-problems>1</expected-problems>
        <code-ref id="camelCaseMethodName"/>
    </test-code>

    <code-fragment id="notCamelCaseMethodName">
        <![CDATA[
        public class Example {

            public int nONCamelCASEMethod() {
                return 0;
            }

            public int camelCaseMethod() {
                return 1;
            }

        }
        ]]>
    </code-fragment>
    <test-code>
        <description>Method names not are in camelCase</description>
        <expected-problems>0</expected-problems>
        <code-ref id="notCamelCaseMethodName"/>
    </test-code>

</test-data>

idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml

<!-- ADD CUSTOM RULE FOR CAMEL CASE METHOD NAME RULE -->
    <rule name="CamelCaseMethodNameRule"
          language="java"
          since="1.6"
          message="demo.CamelCaseMethodNameRule.violation.msg" class="demo.CamelCaseMethodNameRule">
        <priority>5</priority>
    </rule>

p3c-pmd/src/main/java/demo/CamelCaseMethodNameRule.java

public class CamelCaseMethodNameRule extends AbstractJavaRule {

    @Override
    public Object visit(ASTMethodDeclaration node, Object data) {
        String methodName = node.getName();

        // Check if the method name is not in camel case
        if (!isCamelCase(methodName)) {
            addViolationWithMessage(data, node, "demo.CamelCaseMethodNameRule.violation.msg");
        }

        return super.visit(node, data);
    }

    // Method to check if a string is in camel case
    private boolean isCamelCase(String s) {

        System.out.println(s);

        // [a-z]+ -> Matches one or more lowercase letters
        // [A-Z]+ -> Matches one or more uppercase letters
        // \\w+ -> Matches one or more word characters (letters, digits, or underscores)
        // + -> This part of the expression matches one or more occurrences of the previous group, which allows for multiple words in camel case format
        return s.matches("([a-z]+[A-Z]+\\w+)+");
    }
}