From ea9a095b902f5d42126aba4455a64476f5528241 Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Mon, 27 Jan 2020 17:00:05 +0400 Subject: [PATCH] Immutable classes and pure functions/methods annotated (#31) --- src/BigDecimal.php | 21 +++++++++++++++++--- src/BigInteger.php | 17 ++++++++++++++++ src/BigNumber.php | 19 ++++++++++++++++++ src/BigRational.php | 15 ++++++++++++++ src/Exception/DivisionByZeroException.php | 4 ++++ src/Exception/IntegerOverflowException.php | 2 ++ src/Exception/NumberFormatException.php | 2 ++ src/Exception/RoundingNecessaryException.php | 2 ++ src/Internal/Calculator.php | 5 +++++ src/Internal/Calculator/BcMathCalculator.php | 2 ++ src/Internal/Calculator/GmpCalculator.php | 2 ++ src/Internal/Calculator/NativeCalculator.php | 2 ++ 12 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/BigDecimal.php b/src/BigDecimal.php index da0ea64..80c40cb 100644 --- a/src/BigDecimal.php +++ b/src/BigDecimal.php @@ -11,6 +11,8 @@ /** * Immutable, arbitrary-precision signed decimal numbers. + * + * @psalm-immutable */ final class BigDecimal extends BigNumber { @@ -54,6 +56,8 @@ protected function __construct(string $value, int $scale = 0) * @return BigDecimal * * @throws MathException If the value cannot be converted to a BigDecimal. + * + * @psalm-pure */ public static function of($value) : BigNumber { @@ -71,6 +75,8 @@ public static function of($value) : BigNumber * @return BigDecimal * * @throws \InvalidArgumentException If the scale is negative. + * + * @psalm-pure */ public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal { @@ -85,10 +91,13 @@ public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal * Returns a BigDecimal representing zero, with a scale of zero. * * @return BigDecimal + * + * @psalm-pure */ public static function zero() : BigDecimal { - static $zero = null; + /** @psalm-suppress ImpureStaticVariable */ + static $zero; if ($zero === null) { $zero = new BigDecimal('0'); @@ -101,10 +110,13 @@ public static function zero() : BigDecimal * Returns a BigDecimal representing one, with a scale of zero. * * @return BigDecimal + * + * @psalm-pure */ public static function one() : BigDecimal { - static $one = null; + /** @psalm-suppress ImpureStaticVariable */ + static $one; if ($one === null) { $one = new BigDecimal('1'); @@ -117,10 +129,13 @@ public static function one() : BigDecimal * Returns a BigDecimal representing ten, with a scale of zero. * * @return BigDecimal + * + * @psalm-pure */ public static function ten() : BigDecimal { - static $ten = null; + /** @psalm-suppress ImpureStaticVariable */ + static $ten; if ($ten === null) { $ten = new BigDecimal('10'); diff --git a/src/BigInteger.php b/src/BigInteger.php index 64b51b7..ae1b8de 100644 --- a/src/BigInteger.php +++ b/src/BigInteger.php @@ -16,6 +16,8 @@ * * All methods accepting a number as a parameter accept either a BigInteger instance, * an integer, or a string representing an arbitrary size integer. + * + * @psalm-immutable */ final class BigInteger extends BigNumber { @@ -47,6 +49,8 @@ protected function __construct(string $value) * @return BigInteger * * @throws MathException If the value cannot be converted to a BigInteger. + * + * @psalm-pure */ public static function of($value) : BigNumber { @@ -71,6 +75,8 @@ public static function of($value) : BigNumber * * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. * @throws \InvalidArgumentException If the base is out of range. + * + * @psalm-pure */ public static function fromBase(string $number, int $base) : BigInteger { @@ -136,6 +142,8 @@ public static function fromBase(string $number, int $base) : BigInteger * * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. + * + * @psalm-pure */ public static function fromArbitraryBase(string $number, string $alphabet) : BigInteger { @@ -164,9 +172,12 @@ public static function fromArbitraryBase(string $number, string $alphabet) : Big * Returns a BigInteger representing zero. * * @return BigInteger + * + * @psalm-pure */ public static function zero() : BigInteger { + /** @psalm-suppress ImpureStaticVariable */ static $zero; if ($zero === null) { @@ -180,9 +191,12 @@ public static function zero() : BigInteger * Returns a BigInteger representing one. * * @return BigInteger + * + * @psalm-pure */ public static function one() : BigInteger { + /** @psalm-suppress ImpureStaticVariable */ static $one; if ($one === null) { @@ -196,9 +210,12 @@ public static function one() : BigInteger * Returns a BigInteger representing ten. * * @return BigInteger + * + * @psalm-pure */ public static function ten() : BigInteger { + /** @psalm-suppress ImpureStaticVariable */ static $ten; if ($ten === null) { diff --git a/src/BigNumber.php b/src/BigNumber.php index 2ffe729..acd6b3d 100644 --- a/src/BigNumber.php +++ b/src/BigNumber.php @@ -11,6 +11,8 @@ /** * Common interface for arbitrary-precision rational numbers. + * + * @psalm-immutable */ abstract class BigNumber implements \Serializable, \JsonSerializable { @@ -50,6 +52,8 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. + * + * @psalm-pure */ public static function of($value) : BigNumber { @@ -113,6 +117,9 @@ public static function of($value) : BigNumber * @param float $float * * @return string + * + * @psalm-pure + * @psalm-suppress ImpureFunctionCall */ private static function floatToString(float $float) : string { @@ -134,6 +141,8 @@ private static function floatToString(float $float) : string * @param mixed ...$args The arguments to the constructor. * * @return static + * + * @psalm-pure */ protected static function create(... $args) : BigNumber { @@ -151,6 +160,8 @@ protected static function create(... $args) : BigNumber * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. + * + * @psalm-pure */ public static function min(...$values) : BigNumber { @@ -181,6 +192,8 @@ public static function min(...$values) : BigNumber * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. + * + * @psalm-pure */ public static function max(...$values) : BigNumber { @@ -211,6 +224,8 @@ public static function max(...$values) : BigNumber * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. + * + * @psalm-pure */ public static function sum(...$values) : BigNumber { @@ -246,6 +261,8 @@ public static function sum(...$values) : BigNumber * @param BigNumber $b * * @return BigNumber + * + * @psalm-pure */ private static function add(BigNumber $a, BigNumber $b) : BigNumber { @@ -276,6 +293,8 @@ private static function add(BigNumber $a, BigNumber $b) : BigNumber * @param string $number The number, validated as a non-empty string of digits with optional sign. * * @return string + * + * @psalm-pure */ private static function cleanUp(string $number) : string { diff --git a/src/BigRational.php b/src/BigRational.php index a338bec..ff035c5 100644 --- a/src/BigRational.php +++ b/src/BigRational.php @@ -13,6 +13,8 @@ * An arbitrarily large rational number. * * This class is immutable. + * + * @psalm-immutable */ final class BigRational extends BigNumber { @@ -64,6 +66,8 @@ protected function __construct(BigInteger $numerator, BigInteger $denominator, b * @return BigRational * * @throws MathException If the value cannot be converted to a BigRational. + * + * @psalm-pure */ public static function of($value) : BigNumber { @@ -84,6 +88,8 @@ public static function of($value) : BigNumber * @throws NumberFormatException If an argument does not represent a valid number. * @throws RoundingNecessaryException If an argument represents a non-integer number. * @throws DivisionByZeroException If the denominator is zero. + * + * @psalm-pure */ public static function nd($numerator, $denominator) : BigRational { @@ -97,9 +103,12 @@ public static function nd($numerator, $denominator) : BigRational * Returns a BigRational representing zero. * * @return BigRational + * + * @psalm-pure */ public static function zero() : BigRational { + /** @psalm-suppress ImpureStaticVariable */ static $zero; if ($zero === null) { @@ -113,9 +122,12 @@ public static function zero() : BigRational * Returns a BigRational representing one. * * @return BigRational + * + * @psalm-pure */ public static function one() : BigRational { + /** @psalm-suppress ImpureStaticVariable */ static $one; if ($one === null) { @@ -129,9 +141,12 @@ public static function one() : BigRational * Returns a BigRational representing ten. * * @return BigRational + * + * @psalm-pure */ public static function ten() : BigRational { + /** @psalm-suppress ImpureStaticVariable */ static $ten; if ($ten === null) { diff --git a/src/Exception/DivisionByZeroException.php b/src/Exception/DivisionByZeroException.php index 921454a..49a9157 100644 --- a/src/Exception/DivisionByZeroException.php +++ b/src/Exception/DivisionByZeroException.php @@ -11,6 +11,8 @@ class DivisionByZeroException extends MathException { /** * @return DivisionByZeroException + * + * @psalm-pure */ public static function divisionByZero() : DivisionByZeroException { @@ -19,6 +21,8 @@ public static function divisionByZero() : DivisionByZeroException /** * @return DivisionByZeroException + * + * @psalm-pure */ public static function denominatorMustNotBeZero() : DivisionByZeroException { diff --git a/src/Exception/IntegerOverflowException.php b/src/Exception/IntegerOverflowException.php index ab7c203..e0b07d3 100644 --- a/src/Exception/IntegerOverflowException.php +++ b/src/Exception/IntegerOverflowException.php @@ -15,6 +15,8 @@ class IntegerOverflowException extends MathException * @param BigInteger $value * * @return IntegerOverflowException + * + * @psalm-pure */ public static function toIntOverflow(BigInteger $value) : IntegerOverflowException { diff --git a/src/Exception/NumberFormatException.php b/src/Exception/NumberFormatException.php index ffe347c..2fd0be7 100644 --- a/src/Exception/NumberFormatException.php +++ b/src/Exception/NumberFormatException.php @@ -13,6 +13,8 @@ class NumberFormatException extends MathException * @param string $char The failing character. * * @return NumberFormatException + * + * @psalm-pure */ public static function charNotInAlphabet(string $char) : self { diff --git a/src/Exception/RoundingNecessaryException.php b/src/Exception/RoundingNecessaryException.php index 6c7dc17..1c61005 100644 --- a/src/Exception/RoundingNecessaryException.php +++ b/src/Exception/RoundingNecessaryException.php @@ -11,6 +11,8 @@ class RoundingNecessaryException extends MathException { /** * @return RoundingNecessaryException + * + * @psalm-pure */ public static function roundingNecessary() : RoundingNecessaryException { diff --git a/src/Internal/Calculator.php b/src/Internal/Calculator.php index 991563b..061bacd 100644 --- a/src/Internal/Calculator.php +++ b/src/Internal/Calculator.php @@ -17,6 +17,8 @@ * All methods must return strings respecting this format, unless specified otherwise. * * @internal + * + * @psalm-immutable */ abstract class Calculator { @@ -57,10 +59,13 @@ final public static function set(?Calculator $calculator) : void * If none has been explicitly set, the fastest available implementation will be returned. * * @return Calculator + * + * @psalm-pure */ final public static function get() : Calculator { if (self::$instance === null) { + /** @psalm-suppress ImpureMethodCall */ self::$instance = self::detect(); } diff --git a/src/Internal/Calculator/BcMathCalculator.php b/src/Internal/Calculator/BcMathCalculator.php index 6bafb60..944ee9e 100644 --- a/src/Internal/Calculator/BcMathCalculator.php +++ b/src/Internal/Calculator/BcMathCalculator.php @@ -10,6 +10,8 @@ * Calculator implementation built around the bcmath library. * * @internal + * + * @psalm-immutable */ class BcMathCalculator extends Calculator { diff --git a/src/Internal/Calculator/GmpCalculator.php b/src/Internal/Calculator/GmpCalculator.php index cd8a56a..01926da 100644 --- a/src/Internal/Calculator/GmpCalculator.php +++ b/src/Internal/Calculator/GmpCalculator.php @@ -10,6 +10,8 @@ * Calculator implementation built around the GMP library. * * @internal + * + * @psalm-immutable */ class GmpCalculator extends Calculator { diff --git a/src/Internal/Calculator/NativeCalculator.php b/src/Internal/Calculator/NativeCalculator.php index 78123e7..f984f7d 100644 --- a/src/Internal/Calculator/NativeCalculator.php +++ b/src/Internal/Calculator/NativeCalculator.php @@ -10,6 +10,8 @@ * Calculator implementation using only native PHP code. * * @internal + * + * @psalm-immutable */ class NativeCalculator extends Calculator {