<?xml version="1.0"?>

<ruleset name="Finalizer Rules" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../etc/ruleset_xml_schema.xml">
  <description>
These rules deal with different problems that can occur with finalizers.
  </description>

    <rule name="EmptyFinalizer"
          message="Avoid empty finalize methods"
          class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#EmptyFinalizer">
       <description>
If the finalize() method is empty, then it does not need to exist.
       </description>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
  /Block[count(*)=0]
]]>
                </value>
            </property>
        </properties>
        <priority>3</priority>
       <example>
<![CDATA[
public class Foo {
   protected void finalize() {}
}
]]>
       </example>
     </rule>

    <rule name="FinalizeOnlyCallsSuperFinalize"
          message="Finalize should do something besides just calling super.finalize()"
          class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOnlyCallsSuperFinalize">
       <description>
If the finalize() is implemented, it should do something besides just calling
super.finalize().
       </description>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
   /Block[count(BlockStatement)=1]
     /BlockStatement[
       Statement/StatementExpression/PrimaryExpression
      /PrimaryPrefix[@Image="finalize"]
      ]
]]>
                </value>
            </property>
        </properties>
        <priority>3</priority>
       <example>
           <![CDATA[
public class Foo {
   protected void finalize() {
     super.finalize();
   }
}
           ]]>
       </example>
     </rule>

<rule name="FinalizeOverloaded"
      message="Finalize methods should not be overloaded"
      class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOverloaded">
   <description>
Methods named finalize() should not have parameters.  It is
confusing and probably a bug to overload finalize().  It will
not be called by the VM.
   </description>
    <properties>
        <property name="xpath">
            <value>
<![CDATA[
//MethodDeclaration
 /MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]
]]>
            </value>
        </property>
    </properties>
    <priority>3</priority>
   <example>
<![CDATA[
public class Foo {
   // this is confusing and probably a bug
   protected void finalize(int a) {
   }
}
]]>
   </example>
 </rule>

    <rule name="FinalizeDoesNotCallSuperFinalize"
          message="Last statement in finalize method should be a call to super.finalize()"
          class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeDoesNotCallSuperFinalize">
       <description>
If the finalize() is implemented, its last action should be to call super.finalize
       </description>
        <properties>
            <property name="xpath">
                <value>
<!-- in english: a method declaration of finalize(), with no arguments, containing
a block whose last statement is NOT a call to super.finalize -->
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
   /Block
      /BlockStatement[last()]
      [not(Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image='finalize'])]
      [not(Statement/TryStatement/FinallyStatement
       /Block/BlockStatement/Statement/StatementExpression
        /PrimaryExpression/PrimaryPrefix[@Image='finalize'])]
]]>
                </value>
            </property>
        </properties>
        <priority>3</priority>
       <example>
<![CDATA[
public class Foo {
   protected void finalize() {
       something();
       // neglected to call super.finalize()
   }
}
]]>
       </example>
     </rule>

    <rule name="FinalizeShouldBeProtected"
          message="If you override finalize(), make it protected"
          class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeShouldBeProtected">
      <description>
If you override finalize(), make it protected.  If you make
 it public, other classes may call it.
      </description>
        <properties>
            <property name="xpath">
                <value>
                    <![CDATA[
//MethodDeclaration[@Protected="false"]
  /MethodDeclarator[@Image="finalize"]
  [not(FormalParameters/*)]
                    ]]>
                </value>
            </property>
        </properties>
        <priority>3</priority>
      <example>
  <![CDATA[
public class Foo {
 public void finalize() {
  // do something
 }
}
  ]]>
      </example>
    </rule>


    <rule name="AvoidCallingFinalize"
          message="Avoid calling finalize() explicitly"
          class="net.sourceforge.pmd.rules.XPathRule"
          externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#AvoidCallingFinalize">
      <description>
Object.finalize() is called by the garbage collector on an object when garbage collection determines
that there are no more references to the object.
      </description>
      <properties>
          <property name="xpath">
              <value>
    <![CDATA[
//Statement/StatementExpression/PrimaryExpression/PrimaryPrefix
[
./Name[
	@Image='finalize' or ends-with(@Image,'.finalize')
	]
or @Image='finalize'
]
[ancestor::MethodDeclaration/MethodDeclarator[@Image != 'finalize']]
    ]]>
              </value>
          </property>
      </properties>
        <priority>3</priority>
      <example>
<![CDATA[
public class Foo {
 void foo() {
  Bar b = new Bar();
  b.finalize();
 }
}
]]>
      </example>
    </rule>

 </ruleset>



