rspec/rules/S127/java/rule.adoc
2023-09-13 16:44:16 +02:00

79 lines
1.9 KiB
Plaintext

== Why is this an issue?
A `for` loop termination condition should test the loop counter against an invariant value that does not change during the execution of the loop.
Invariant termination conditions make the program logic easier to understand and maintain.
This rule tracks three types of non-invariant termination conditions:
* When the loop counters are updated in the body of the `for` loop
* When the termination condition depends on a method call
* When the termination condition depends on an object property since such properties could change during the execution of the loop.
== How to fix it
=== Code examples
==== Noncompliant code example
Make the termination condition invariant by using a constant or a local variable instead of an expression that could change during the execution of the loop.
[source,java,diff-id=1,diff-type=noncompliant]
----
for (int i = 0; i < foo(); i++) { // Noncompliant, "foo()" is not an invariant
// ...
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
int end = foo();
for (int i = 0; i < end; i++) { // Compliant, "end" does not change during loop execution
// ...
}
----
==== Noncompliant code example
If this is impossible and the counter variable must be updated in the loop's body, use a `while` or `do` `while` loop instead of a `for` loop.
[source,java,diff-id=2,diff-type=noncompliant]
----
for (int i = 0; i < 10; i++) {
// ...
if (condition) i++; // Noncompliant, i is updated from within body
// ...
}
----
==== Compliant solution
[source,java,diff-id=2,diff-type=compliant]
----
int i = 0;
while (i++ < 10) { // Compliant
// ...
if (condition) sum++;
// ...
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::../message.adoc[]
include::../parameters.adoc[]
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]