diff --git a/README.md b/README.md index e1ee8abe5..a60bca098 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ -# Sonarqube-repair +# Sonarqube-repair [![Travis Build Status](https://travis-ci.com/kth-tcs/sonarqube-repair.svg?branch=master)](https://travis-ci.com/kth-tcs/sonarqube-repair) -Sonarqube-repair is a collection of java code transformations made with the [Spoon](https://github.com/INRIA/spoon) library to repair violations of static rules defined by [SonarQube](https://rules.sonarsource.com). +Sonarqube-repair is a collection of java code analyses and transformations made with the [Spoon](https://github.com/INRIA/spoon) library to repair violations of rules contained in [SonarQube](https://rules.sonarsource.com). -## Handled SonarQube rules +## Handled rules -Sonarqube-repair can currently repair violations of 7 SonarQube rules of which 5 are labeled as `BUG` and 2 as `Code Smell`. [Checkout out the handled rules](/docs/HANDLED_SONARQUBE_RULES.md). +Sonarqube-repair can currently repair violations of 7 rules of which 5 are labeled as `BUG` and 2 as `Code Smell`. [Check out the handled rules](/docs/HANDLED_RULES.md). + +## Getting started -## Getting Started ### Prerequisites -A JDK (java 1.8 or above) + +A JDK (java 1.8) ### Usage @@ -28,11 +30,13 @@ A JDK (java 1.8 or above) $ cd sonarqube-repair $ mvn package -DskipTests $ ls target/*jar -target/sonarqube-repair-0.1-SNAPSHOT.jar target/sonarqube-repair-0.1-SNAPSHOT-jar-with-dependencies.jar target/sonarqube-repair-0.1-SNAPSHOT-javadoc.jar +target/sonarqube-repair-0.1-SNAPSHOT.jar +target/sonarqube-repair-0.1-SNAPSHOT-jar-with-dependencies.jar +target/sonarqube-repair-0.1-SNAPSHOT-javadoc.jar $ java -jar target/sonarqube-repair-0.1-SNAPSHOT-jar-with-dependencies.jar ``` -For the arguments, provide the Sonar rule key (see the supported rules [here](/docs/HANDLED_SONARQUBE_RULES.md)). +For the arguments, provide the Sonar rule key (see the supported rules [here](/docs/HANDLED_RULES.md)). For the rules 2095, 1854, and 1948, also provide the project key for the Sonar analysis (the url of the Sonar analysis of your project should be set in `src/main/java/sonarquberepair/processor/sonarbased/SonarWebAPIBasedProcessor.java` if it is different from [sonarcloud.io](https://sonarcloud.io/about)). Finally, the repaired files will appear in `sonarqube-repair/spooned/`. @@ -43,13 +47,7 @@ To run Sonarqube-repair on projects towards proposing fixes in the form of PRs, ## Contributing -Contributions are welcome! Feel free to open issues on this GitHub repository, and also to open pull requests for making this project nicer. - -## Authors -* Ashutosh Kumar Verma ([@ashutosh1598](https://github.com/ashutosh1598)) -* Martin Monperrus ([@monperrus](https://github.com/monperrus)) -* Pavel Pvojtechovsky ([@pvojtechovsky](https://github.com/pvojtechovsky)) -* Haris Adzemovic ([@HarisAdzemovic](https://github.com/HarisAdzemovic)) +Contributions are welcome! Feel free to open issues on this GitHub repository, and also to open pull requests for making this project nicer (see instructions [here](/docs/CONTRIBUTING.md)). ## Implementation notes diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 000000000..672afc435 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,62 @@ +## Contributing + +Pull requests are very welcome by the Sonarqube-repair team! + +### Guidelines for all pull-requests + +A PR will be accepted and merged when: + +- It is minimal in the sense of doing a single thing (for example, an addition of a single new processor and a single bug fix). +- It has a clear explanation of its goal and what was changed. +- It passes in the continuous integration service being used in the project. + +### Guidelines for new-processor pull-requests + +For adding a new processor in Sonarqube-repair, please, follow the instructions described below. + +1) Find the name for the new processor + +The first step is to find the name for the new processor. +To do so, you need to find the name that SonarSource uses for the rule that the new processor targets. +So let's suppose that the new processor targets the rule ["Math operands should be cast before assignment"](https://rules.sonarsource.com/java/type/Bug/RSPEC-2184), rule key 2184. +In [SonarSource for Java](https://github.com/SonarSource/sonar-java/tree/master/java-checks/src/main/java/org/sonar/java/checks), you will find that such a rule is implemented by the class `CastArithmeticOperandCheck`. +So the name of your new processor is `CastArithmeticOperandCheck` replacing "Check" by "Processor", resulting in `CastArithmeticOperandProcessor`. + +2) Create the processor + +Once you have the name for the new processor, you can create a class using that name in `src/main/java/sonarquberepair.processor.spoonbased`. +This new class must extend `AbstractProcessor` and implement the methods `isToBeProcessed` and `process` (check out real examples of processors [here](/src/main/java/sonarquberepair/processor/spoonbased)). +After implementing your new processor, plug it in Sonarqube-repair by adding it in the code of [Processors](/src/main/java/sonarquberepair/Processors.java). + +3) Create a test class for the processor + +Your processor is done, so now it's time to test it. +For that, you should first to create a test class, with the same name as your processor plus the word "Test", and place it in [here](/src/test/java/sonarquberepair/processor/spoonbased). +See in this same folder how the tests usually are. +Then, you should create a java file in the [testing resources](/src/test/resources), which is the file you will use in your test class. +Such a resource should contain at least the examples that SonarSource provides, because your processor should at least work on them. +You can find the examples provided by SonarSource in its [rules' webpage](https://rules.sonarsource.com/java) and in its own [testing resources](https://github.com/SonarSource/sonar-java/tree/master/java-checks-test-sources/src/main/java/checks) (note that different testing cases might exist in both locations, thus both ones should be checked). + +4) Update documentation + +Your processor is done, it's passing the minimum tests, so now you can update the documentation. +There are two files that you should update: [README.md](/README.md) and [HANDLED_RULES.md](/docs/HANDLED_RULES.md). +In the `README.md` file, you should only uṕdate the number of rules handled by Sonarqube-repair. +In the `HANDLED_RULES.md` file, you should do the same, but you should also add the new handled rule in the table of contents and a summary of its processor with an example. +You should do it following the same way as the existing handled rules are documented. + +5) Open a PR + +The processor, the tests, and the documentation being ready, your contribution is also ready to be used in a PR. +Open a PR, with the title "Add (SonarSource rule )". +For the description of the PR, use the following template: + +This PR adds a processor for the rule [](LINK TO THE RULE IN THE https://rules.sonarsource.com/java WEBPAGE). + +Transformation: + +```diff + +``` + +And then you can submit your PR! diff --git a/docs/HANDLED_SONARQUBE_RULES.md b/docs/HANDLED_RULES.md similarity index 73% rename from docs/HANDLED_SONARQUBE_RULES.md rename to docs/HANDLED_RULES.md index 69212fb13..0d7c92ac5 100644 --- a/docs/HANDLED_SONARQUBE_RULES.md +++ b/docs/HANDLED_RULES.md @@ -1,16 +1,16 @@ -## Handled SonarQube rules +## Handled rules -Sonarqube-repair can currently repair violations of 7 SonarQube rules of which 5 are labeled as `Bug` and 2 as `Code Smell`: +Sonarqube-repair can currently repair violations of 7 rules of which 5 are labeled as `BUG` and 2 as `Code Smell`: -* [Bug](HANDLED_SONARQUBE_RULES.md#*Bug*) - * [Resources should be closed](HANDLED_SONARQUBE_RULES.md#resources-should-be-closed-sonar-rule-2095httpsrulessonarsourcecomjavarspec-2095) ([Sonar Rule 2095](https://rules.sonarsource.com/java/RSPEC-2095)) - * ["BigDecimal(double)" should not be used](HANDLED_SONARQUBE_RULES.md#bigdecimaldouble-should-not-be-used-sonar-rule-2111httpsrulessonarsourcecomjavarspec-2111) ([Sonar Rule 2111](https://rules.sonarsource.com/java/RSPEC-2111)) - * ["hashCode" and "toString" should not be called on array instances](HANDLED_SONARQUBE_RULES.md#hashcode-and-tostring-should-not-be-called-on-array-instances-sonar-rule-2116httpsrulessonarsourcecomjavarspec-2116) ([Sonar Rule 2116](https://rules.sonarsource.com/java/RSPEC-2116)) - * ["Iterator.next()" methods should throw "NoSuchElementException"](HANDLED_SONARQUBE_RULES.md#iteratornext-methods-should-throw-nosuchelementexception-sonar-rule-2272httpsrulessonarsourcecomjavarspec-2272) ([Sonar Rule 2272](https://rules.sonarsource.com/java/RSPEC-2272)) - * [Strings and Boxed types should be compared using "equals()"](HANDLED_SONARQUBE_RULES.md#strings-and-boxed-types-should-be-compared-using-equals-sonar-rule-4973httpsrulessonarsourcecomjavarspec-4973) ([Sonar Rule 4973](https://rules.sonarsource.com/java/RSPEC-4973)) -* [Code Smell](HANDLED_SONARQUBE_RULES.md#*Code Smell*) - * [Unused assignments should be removed](HANDLED_SONARQUBE_RULES.md#unused-assignments-should-be-removed-sonar-rule-1854httpsrulessonarsourcecomjavarspec-1854) ([Sonar Rule 1854](https://rules.sonarsource.com/java/RSPEC-1854)) - * [Fields in a "Serializable" class should either be transient or serializable](HANDLED_SONARQUBE_RULES.md#fields-in-a-serializable-class-should-either-be-transient-or-serializable-sonar-rule-1948httpsrulessonarsourcecomjavarspec-1948) ([Sonar Rule 1948](https://rules.sonarsource.com/java/RSPEC-1948)) +* [Bug](HANDLED_RULES.md#bug) + * [Resources should be closed](HANDLED_RULES.md#resources-should-be-closed-sonar-rule-2095httpsrulessonarsourcecomjavarspec-2095) ([Sonar Rule 2095](https://rules.sonarsource.com/java/RSPEC-2095)) + * ["BigDecimal(double)" should not be used](HANDLED_RULES.md#bigdecimaldouble-should-not-be-used-sonar-rule-2111httpsrulessonarsourcecomjavarspec-2111) ([Sonar Rule 2111](https://rules.sonarsource.com/java/RSPEC-2111)) + * ["hashCode" and "toString" should not be called on array instances](HANDLED_RULES.md#hashcode-and-tostring-should-not-be-called-on-array-instances-sonar-rule-2116httpsrulessonarsourcecomjavarspec-2116) ([Sonar Rule 2116](https://rules.sonarsource.com/java/RSPEC-2116)) + * ["Iterator.next()" methods should throw "NoSuchElementException"](HANDLED_RULES.md#iteratornext-methods-should-throw-nosuchelementexception-sonar-rule-2272httpsrulessonarsourcecomjavarspec-2272) ([Sonar Rule 2272](https://rules.sonarsource.com/java/RSPEC-2272)) + * [Strings and Boxed types should be compared using "equals()"](HANDLED_RULES.md#strings-and-boxed-types-should-be-compared-using-equals-sonar-rule-4973httpsrulessonarsourcecomjavarspec-4973) ([Sonar Rule 4973](https://rules.sonarsource.com/java/RSPEC-4973)) +* [Code Smell](HANDLED_RULES.md#code-smell) + * [Unused assignments should be removed](HANDLED_RULES.md#unused-assignments-should-be-removed-sonar-rule-1854httpsrulessonarsourcecomjavarspec-1854) ([Sonar Rule 1854](https://rules.sonarsource.com/java/RSPEC-1854)) + * [Fields in a "Serializable" class should either be transient or serializable](HANDLED_RULES.md#fields-in-a-serializable-class-should-either-be-transient-or-serializable-sonar-rule-1948httpsrulessonarsourcecomjavarspec-1948) ([Sonar Rule 1948](https://rules.sonarsource.com/java/RSPEC-1948)) ### *Bug* @@ -89,9 +89,11 @@ Any implementation of the `Iterator.next()` method that does not throw `NoSuchEl Example: ```diff +import java.util.NoSuchElementException; + +public class IteratorNextException implements Iterator { ... @Override -- public String next(){ // Noncompliant +- public String next() { // Noncompliant + public String next() { + if (!hasNext()) { + throw new NoSuchElementException(); @@ -110,11 +112,11 @@ Any comparison of strings or boxed types using `==` or `!=` is replaced by `equa Example: ```diff -- return b != a;// Noncompliant -+ return !b.equals(a); +- if (firstName == lastName) // Noncompliant ++ if (firstName.equals(lastName)) ... -- if(firstName == lastName){// Noncompliant -+ if (firstName.equals(lastName)) { +- return b != a; // Noncompliant ++ return !b.equals(a); ``` Check out an accepted PR in [Apache Sling Discovery](https://github.com/apache/sling-org-apache-sling-discovery-impl/pull/1) that repairs one CompareStringsBoxedTypesWithEquals violation. diff --git a/docs/IMPLEMENTATION_NOTES.md b/docs/IMPLEMENTATION_NOTES.md index bc80449d1..abf6db8ea 100644 --- a/docs/IMPLEMENTATION_NOTES.md +++ b/docs/IMPLEMENTATION_NOTES.md @@ -1,5 +1,5 @@ ## Implementation notes -The processors for the rules 1854, 1948, and 2095 are written in a different way from the others, using the Sonar web API for localising bugs. -The processors and their implementations have not been maintained and your milage may vary. -The remaining processors leverage the capabilities of Spoon for both localising and repairing violations. +The processors for the rules 1854, 1948, and 2095 are written in a different way from the others, using the Sonar web API for localizing bugs. +These processors have not been maintained and your milage may vary. +The remaining processors leverage the capabilities of Spoon for both localizing and repairing violations.