<?xml version="1.0" encoding="UTF-8"?>

<ruleset name="Code Style"
         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 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">

    <description>
Rules which enforce a specific coding style.
    </description>

    <rule name="ClassNamingConventions"
          language="apex"
          since="5.5.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.ClassNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#classnamingconventions">
        <description>
            Configurable naming conventions for type declarations. This rule reports
            type declarations which do not match the regex that applies to their
            specific kind (e.g. enum or interface). Each regex can be configured through
            properties.

            By default this rule uses the standard Apex naming convention (Pascal case).
        </description>
        <priority>1</priority>
        <example>
            <![CDATA[
public class FooClass { } // This is in pascal case, so it's ok

public class fooClass { } // This will be reported unless you change the regex
]]>
        </example>
    </rule>

    <rule name="IfElseStmtsMustUseBraces"
          language="apex"
          since="5.6.0"
          message="Avoid using 'if...else' statements without curly braces"
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#ifelsestmtsmustusebraces">
        <description>
Avoid using if..else statements without using surrounding braces. If the code formatting
or indentation is lost then it becomes difficult to separate the code being controlled
from the rest.
        </description>
        <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0]
|
//IfElseBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0]
]]>
                </value>
            </property>
        </properties>
        <example>
<![CDATA[
// this is OK
if (foo) x++;

// but this is not
if (foo)
    x = x+1;
else
    x = x-1;
]]>
        </example>
    </rule>

    <rule name="IfStmtsMustUseBraces"
          language="apex"
          since="5.6.0"
          message="Avoid using if statements without curly braces"
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#ifstmtsmustusebraces">
        <description>
Avoid using if statements without using braces to surround the code block. If the code
formatting or indentation is lost then it becomes difficult to separate the code being
controlled from the rest.
        </description>
        <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace= false()]
]]>
                </value>
            </property>
        </properties>
        <example>
 <![CDATA[
if (foo)    // not recommended
    x++;

if (foo) {  // preferred approach
    x++;
}
]]>
        </example>
    </rule>

    <rule name="FieldDeclarationsShouldBeAtStart"
          language="apex"
          since="6.23.0"
          message="Field declaration for ''{0}'' should be before method declarations in its class"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.FieldDeclarationsShouldBeAtStartRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#fielddeclarationsshouldbeatstart">
        <description>
            Field declarations should appear before method declarations within a class.
        </description>
        <priority>3</priority>
        <example>
<![CDATA[
class Foo {
    public Integer someField; // good

    public void someMethod() {
    }

    public Integer anotherField; // bad
}
]]>
        </example>
    </rule>

    <rule name="FieldNamingConventions"
          language="apex"
          since="6.15.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.FieldNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#fieldnamingconventions">
        <description>
            Configurable naming conventions for field declarations. This rule reports variable declarations
            which do not match the regex that applies to their specific kind ---e.g. constants (static final),
            static field, final field. Each regex can be configured through properties.

            By default this rule uses the standard Apex naming convention (Camel case).
        </description>
        <priority>1</priority>
        <example>
<![CDATA[
public class Foo {
    Integer instanceField; // This is in camel case, so it's ok

    Integer INSTANCE_FIELD; // This will be reported unless you change the regex
}
]]>
        </example>
    </rule>

    <rule name="ForLoopsMustUseBraces"
          language="apex"
          since="5.6.0"
          message="Avoid using 'for' statements without curly braces"
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#forloopsmustusebraces">
        <description>
Avoid using 'for' statements without using surrounding braces. If the code formatting or
indentation is lost then it becomes difficult to separate the code being controlled
from the rest.
        </description>
        <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//ForLoopStatement/BlockStatement[@CurlyBrace= false()]
|
//ForEachStatement/BlockStatement[@CurlyBrace= false()]
]]>
                </value>
            </property>
        </properties>
        <example>
<![CDATA[
for (int i = 0; i < 42; i++) // not recommended
    foo();

for (int i = 0; i < 42; i++) { // preferred approach
    foo();
}
]]>
        </example>
    </rule>

    <rule name="FormalParameterNamingConventions"
          language="apex"
          since="6.15.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.FormalParameterNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#formalparameternamingconventions">
        <description>
            Configurable naming conventions for formal parameters of methods.
            This rule reports formal parameters which do not match the regex that applies to their
            specific kind (e.g. method parameter, or final method parameter). Each regex can be
            configured through properties.

            By default this rule uses the standard Apex naming convention (Camel case).
        </description>
        <priority>1</priority>
        <example>
<![CDATA[
public class Foo {
    public bar(Integer methodParameter) { } // This is in camel case, so it's ok

    public baz(Integer METHOD_PARAMETER) { } // This will be reported unless you change the regex
}
]]>
        </example>
    </rule>

    <rule name="LocalVariableNamingConventions"
          language="apex"
          since="6.15.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.LocalVariableNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#localvariablenamingconventions">
        <description>
            Configurable naming conventions for local variable declarations.
            This rule reports variable declarations which do not match the regex that applies to their
            specific kind (e.g. local variable, or final local variable). Each regex can be configured through
            properties.

            By default this rule uses the standard Apex naming convention (Camel case).
        </description>
        <priority>1</priority>
        <example>
<![CDATA[
public class Foo {
    public Foo() {
        Integer localVariable; // This is in camel case, so it's ok

        Integer LOCAL_VARIABLE; // This will be reported unless you change the regex
    }
}
]]>
        </example>
    </rule>

    <rule name="MethodNamingConventions"
          language="apex"
          since="5.5.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.MethodNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#methodnamingconventions">
        <description>
            Configurable naming conventions for method declarations. This rule reports
            method declarations which do not match the regex that applies to their
            specific kind (e.g. static method, or test method). Each regex can be
            configured through properties.

            By default this rule uses the standard Apex naming convention (Camel case).
        </description>
        <priority>1</priority>
        <example>
<![CDATA[
public class Foo {
    public void instanceMethod() { } // This is in camel case, so it's ok

    public void INSTANCE_METHOD() { } // This will be reported unless you change the regex
]]>
        </example>
    </rule>

    <rule name="OneDeclarationPerLine"
          language="apex"
          since="6.7.0"
          message="Use one statement for each line, it enhances code readability."
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#onedeclarationperline">
        <description>
Apex allows the use of several variables declaration of the same type on one line. However, it
can lead to quite messy code. This rule looks for several declarations on the same line.
        </description>
        <priority>1</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//VariableDeclarationStatements
  [count(VariableDeclaration) > 1 and ($reportInForLoopInitializer = true() or name(parent::*) != 'ForLoopStatement')]
  [$strictMode or count(distinct-values(VariableDeclaration/@BeginLine)) != count(VariableDeclaration)]
|
//FieldDeclarationStatements
  [count(FieldDeclaration) > 1]
  [$strictMode or count(distinct-values(FieldDeclaration/VariableExpression/@BeginLine)) != count(FieldDeclaration/VariableExpression)]
]]>
                </value>
            </property>
            <property name="strictMode" type="Boolean" value="false"
                      description="If true, mark combined declaration even if the declarations are on separate lines."/>
            <property name="reportInForLoopInitializer" type="Boolean" value="true" description="If false, multiple declarations in a for loop initializer are not flagged."/>
        </properties>
        <example>
<![CDATA[
Integer a, b;   // not recommended

Integer a,
        b;      // ok by default, can be flagged setting the strictMode property

Integer a;      // preferred approach
Integer b;
]]>
        </example>
    </rule>

    <rule name="PropertyNamingConventions"
          language="apex"
          since="6.15.0"
          message="The {0} name ''{1}'' doesn''t match ''{2}''"
          class="net.sourceforge.pmd.lang.apex.rule.codestyle.PropertyNamingConventionsRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#propertynamingconventions">
        <description>
            Configurable naming conventions for property declarations. This rule reports
            property declarations which do not match the regex that applies to their
            specific kind (e.g. static property, or instance property). Each regex can be
            configured through properties.

            By default this rule uses the standard Apex naming convention (Camel case).
        </description>
        <priority>1</priority>
        <example>
<![CDATA[
public class Foo {
    public Integer instanceProperty { get; set; } // This is in camel case, so it's ok

    public Integer INSTANCE_PROPERTY { get; set; } // This will be reported unless you change the regex
}
]]>
        </example>
    </rule>

    <rule name="WhileLoopsMustUseBraces"
          language="apex"
          since="5.6.0"
          message="Avoid using 'while' statements without curly braces"
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#whileloopsmustusebraces">
        <description>
Avoid using 'while' statements without using braces to surround the code block. If the code
formatting or indentation is lost then it becomes difficult to separate the code being
controlled from the rest.
        </description>
        <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//WhileLoopStatement/BlockStatement[@CurlyBrace= false()]
]]>
                </value>
            </property>
        </properties>
        <example>
<![CDATA[
while (true)    // not recommended
    x++;

while (true) {  // preferred approach
    x++;
}
]]>
        </example>
    </rule>
</ruleset>
