diff --git a/rules/S6913/java/metadata.json b/rules/S6913/java/metadata.json new file mode 100644 index 0000000000..00d8c734c8 --- /dev/null +++ b/rules/S6913/java/metadata.json @@ -0,0 +1,23 @@ +{ + "title": "\"Math.clamp\" should be used with correct ranges", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-6913", + "sqKey": "S6913", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "MAINTAINABILITY": "MEDIUM" + }, + "attribute": "CONVENTIONAL" + } +} diff --git a/rules/S6913/java/rule.adoc b/rules/S6913/java/rule.adoc new file mode 100644 index 0000000000..a3539292f0 --- /dev/null +++ b/rules/S6913/java/rule.adoc @@ -0,0 +1,65 @@ +== Why is this an issue? + +Java 21 introduces the new method `Math.clamp(value, min, max)` that fits a value within a specified interval. +Before Java 21, this behavior required explicit calls to the `Math.min` and `Math.max` methods, as in `Math.max(min, Math.min(value, max))`. + +If `min > max`, `Math.clamp` throws an `IllegalArgumentException`, indicating an invalid interval. +This can occur if the `min` and `max` arguments are mistakenly reversed. + +Note that `Math.clamp` is not a general substitute for `Math.min` or `Math.max`, but for the combination of both. +If `value` is the same as `min` or `max`, using `Math.clamp` is unnecessary and `Math.min` or `Math.max` should be used instead. + +== How to fix it + +- Use `Math.clamp(value, min, max)` instead of `Math.clamp(value, max, min)`. +- If `value` is the same as `min`, use `Math.min(value, max)` instead. +- If `value` is the same as `max`, use `Math.max(min, value)` instead. + +=== Code examples + +==== Noncompliant code example + +[source,java,diff-id=1,diff-type=noncompliant] +---- +Math.clamp(red, 1f, 0f); // Noncompliant, [1,0] is not a valid range +---- + +==== Compliant solution + +[source,java,diff-id=1,diff-type=compliant] +---- +Math.clamp(red, 0f, 1f); // Compliant +---- + +==== Noncompliant code example + +[source,java,diff-id=2,diff-type=noncompliant] +---- +Math.clamp(red, red, 1f); // Noncompliant, use Math.min(red, 1f) +---- + +==== Compliant solution + +[source,java,diff-id=2,diff-type=compliant] +---- +Math.min(red, 1f) // Compliant +---- + +==== Noncompliant code example + +[source,java,diff-id=3,diff-type=noncompliant] +---- +Math.clamp(red, 0f, red); // Noncompliant, use Math.max(0f, red) +---- + +==== Compliant solution + +[source,java,diff-id=3,diff-type=compliant] +---- +Math.min(0f, red) // Compliant +---- + + +== Resources + +* Java Documentation - https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html#clamp(long,int,int)[Math.clamp] diff --git a/rules/S6913/metadata.json b/rules/S6913/metadata.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/rules/S6913/metadata.json @@ -0,0 +1,2 @@ +{ +}