# RPG

*RPG is available starting in* [*Enterprise Edition*](https://www.sonarsource.com/plans-and-pricing/enterprise/)*.*

### Language-specific properties <a href="#language-specific-properties" id="language-specific-properties"></a>

Discover and update the RPG-specific [analysis-parameters](https://docs.sonarsource.com/sonarqube-server/10.7/analyzing-source-code/analysis-parameters "mention") in **Administration** > **Configuration** > **General Settings** > **Languages** > **RPG**

### Source code extraction <a href="#source-code-extraction" id="source-code-extraction"></a>

In order to analyze your source code with SonarQube you need to first extract it onto a filesystem. You can use your own tool or an open-source tool; SonarSource does not provide any connectors or source code extraction tools.

### RPG source format <a href="#rpg-source-format" id="rpg-source-format"></a>

Depending on your extraction process, your RPG source files may include an extra margin on the left of the 80 columns used for code. This margin is in addition to the standard margin which takes up characters 1-5 in the 80-character source format (when "fully free-form" is not used). The extra margin is controlled through the `sonar.rpg.leftMarginWidth` property. By default, it is set to 12, which is the size of the margin in an IBM "source physical file". If your RPG source files do not contain such a margin, you should set `sonar.rpg.leftMarginWidth` to `0`.

You can find an [example file](https://raw.githubusercontent.com/SonarSource/sonar-scanning-examples/master/sonar-scanner/src/rpg/MYPROGRAM.rpg) illustrating a 12-character margin in our sample project.

You should also make sure to set `sonar.sourceEncoding` to the appropriate encoding. Please check the [analysis-parameters](https://docs.sonarsource.com/sonarqube-server/10.7/analyzing-source-code/analysis-parameters "mention").

### Free-Form Support <a href="#free-form-support" id="free-form-support"></a>

Free-form is supported for all kinds of specifications and SQL statements that exist in IBM i 7.4. Fully free-form code (starting with `**FREE`) is also supported.

### Language version support <a href="#language-version-support" id="language-version-support"></a>

RPG III and RPG/400 are not supported. If your operation codes are on column 28, you are using RPG III. Please refer to IBM™ [documentation](https://www.ibm.com/docs/en/i/7.5?topic=appendixes-appendix-b-using-rpg-iii-rpg-iv-conversion-aid) to convert your code.

The analyzer supports RPG starting from RPG IV (ILE RPG) on platform IBM™ i version V3R1 on onwards

### Custom Rules for RPG <a href="#custom-rules-for-rpg" id="custom-rules-for-rpg"></a>

To get started you can [browse](https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/rpg-custom-rules) or [download](https://github.com/SonarSource/sonar-custom-rules-examples/archive/master.zip) a simple plugin.

#### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* JDK 8
* sonar-rpg-plugin 2.0+

#### Creating a Maven project <a href="#creating-a-maven-project" id="creating-a-maven-project"></a>

You should first create a Maven project: re-using the [pom.xml from the RPG example](https://github.com/SonarSource/sonar-custom-rules-examples/blob/master/rpg-custom-rules/pom.xml) is a good start.

The following dependencies need to be defined in the `pom.xml`:

* `sonar-plugin-api` to get access to SonarQube APIs.
* `sonar-rpg-plugin` to use the APIs of the RPG plugin.

#### Writing a custom rule <a href="#writing-a-custom-rule" id="writing-a-custom-rule"></a>

Each rule needs to be defined in a class which:

* Implements [`com.sonarsource.rpg.api.checks.Check`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/checks/Check.html). Instead of implementing this interface directly, the class can also extend [`VisitorBasedCheck`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/checks/VisitorBasedCheck.html) which makes it easier to target some specific parts of the analyzed source code.
* Has an `org.sonar.check.Rule` annotation to define the key of the rule.

**Navigating the syntax tree**

The analyzed source code is represented as a tree structure. The top-most tree is an instance of [`ModuleTree`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/tree/ModuleTree.html) which has references to other trees. Some of the trees represent a group of RPG calculations (for example, an `IF` group is represented as a tree that references the calculations which are executed when the condition is true), and some others represent expressions such as `a + b`.

The instance of [`CheckContext`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/checks/CheckContext.html) which is passed to the checks gives a reference to the `ModuleTree` of the analyzed source code. The whole tree structure can be navigated from that object.

Most often, it’s easier to extend `VisitorBasedCheck` and to override one or more methods whose name starts with `visit`, e.g. `visitIfGroup`. That way, it’s possible to define what should be executed when visiting some specific kinds of trees.

**Creating issues**

[`CheckContext`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/checks/CheckContext.html) provides methods to create issues either at the file or line level.

**Testing the rule**

It’s possible to write unit tests for custom rules using `com.sonarsource.rpg.api.test.RpgCheckVerifier`. This utility class executes a custom rule against a given RPG test file. The RPG test file should contain comments denoting lines where issues should be expected:

* if the line ends with "// Noncompliant", `RpgCheckVerifier` expects an issue on that line.
* if the line ends with "// Noncompliant {{my message}}", `RpgCheckVerifier` expects an issue on that line and checks that the issue message is "my message".

The example project contains an [example test class](https://github.com/SonarSource/sonar-custom-rules-examples/blob/master/rpg-custom-rules/src/test/java/com/sonarsource/rpg/example/checks/DataStructureNamingConventionCheckTest.java) and the [associated RPG file](https://github.com/SonarSource/sonar-custom-rules-examples/blob/master/rpg-custom-rules/src/test/resources/data-structure-name.rpg).

#### Rules definition <a href="#rules-definition" id="rules-definition"></a>

One class should extend [`com.sonarsource.rpg.api.CustomRulesDefinition`](https://javadocs.sonarsource.org/rpg/apidocs/3.1.0/com/sonarsource/rpg/api/CustomRulesDefinition.html): it should list the classes of the custom rules and use the SonarQube API to define the metadata of these rules: name, HTML description, default severity.

#### Plugin class <a href="#plugin-class" id="plugin-class"></a>

The entry point of the custom plugin is a class that lists SonarQube extensions. This list should contain the class created in the previous step.

#### Packaging the custom plugin <a href="#packaging-the-custom-plugin" id="packaging-the-custom-plugin"></a>

To package your custom plugin, the pom.xml should use `org.sonarsource.sonar-packaging-maven-plugin`, as described in the [plugin-basics](https://docs.sonarsource.com/sonarqube-server/10.7/extension-guide/developing-a-plugin/plugin-basics "mention").

In the configuration for `sonar-packaging-maven-plugin`, `basePlugin` should be set to `rpg`.

Building the Maven project will produce a JAR file that can be deployed to a SonarQube server.

#### Configuring plugins for analyzer loading optimization <a href="#configuring-plugins-for-analyzer-loading-optimization" id="configuring-plugins-for-analyzer-loading-optimization"></a>

By default, the loading of analyzers is optimized (see [improving-performance](https://docs.sonarsource.com/sonarqube-server/10.7/server-upgrade-and-maintenance/maintenance/improving-performance "mention")), SonarQube will only download analyzers and third-party plugins for the detected languages before running an analysis.

When creating custom plugins, to prevent errors when projects are analyzed, you must use the `requiredForLanguages` property in your plugin’s `pom.xml` file to specify the languages your plugin supports. Without this property, your plugin will be executed unconditionally during analysis, even when its language-specific dependencies are unavailable. See [plugin-basics](https://docs.sonarsource.com/sonarqube-server/10.7/extension-guide/developing-a-plugin/plugin-basics "mention") for details on this behavior and the `requiredForLanguages` property.

```css-79elbk
<configuration>
   [...]
   <requiredForLanguages>RPG</requiredForLanguages>
</configuration>
```
