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

<ruleset name="Best Practices"
    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 generally accepted best practices.
    </description>

    <rule name="ProhibitedInterfaceBuilder"
          since="7.0.0"
          language="swift"
          message="Creating views using Interface Builder should be avoided."
          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder">
        <description>
            Creating views using Interface Builder should be avoided.
            Defining views by code allows the compiler to detect issues that otherwise will be runtime errors.
            It's difficult to review the auto-generated code and allow concurrent modifications of those files.
            Consider building views programmatically.
        </description>
        <priority>2</priority>
        <properties>
            <property name="xpath">
                <value>
                    //VariableDeclarationHead/Attributes/Attribute[AttributeName/Identifier/T-Identifier[@Text = "IBOutlet"]]
                    |
                    //FunctionHead/Attributes/Attribute[AttributeName/Identifier/T-Identifier[@Text = "IBAction"]]
                </value>
            </property>
        </properties>
        <example>
            <![CDATA[
class ViewController: UIViewController {
    @IBOutlet var label: UILabel! // violation, referencing a IBOutlet
}

class ViewController: UIViewController {
    var label: UILabel!
}
]]>
        </example>
    </rule>

    <rule name="UnavailableFunction"
          since="7.0.0"
          language="swift"
          message="Unimplemented functions should be marked as unavailable."
          class="net.sourceforge.pmd.lang.swift.rule.bestpractices.UnavailableFunctionRule"
          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_bestpractices.html#unavailablefunction">
        <description>
            Due to Objective-C and Swift interoperability some functions are often required to be implemented but
            aren't really needed. It is extremely common that the sole implementation of the functions consist of throwing
            a fatal error. Marking these functions as unavailable prevents them from being executed while still making
            the compiler happy.
        </description>
        <priority>3</priority>
        <example>
            <![CDATA[
required init?(coder _: NSCoder) { // violation, no unavailable attribute added to the function declaration
    fatalError("init(coder:) has not been implemented")
}

@available(*, unavailable)         // no violation
required init?(coder _: NSCoder) {
    fatalError("init(coder:) has not been implemented")
]]>
        </example>
    </rule>
</ruleset>
