From 52aeeb290e57732c82c8f741396efcfda1c5a2d1 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Thu, 20 Jan 2022 16:06:31 -0500 Subject: [PATCH 1/5] Use objects, not strings, for assertions --- phpcs.xml | 4 + psalm.xml.dist | 6 + src/Psalm/Context.php | 12 +- src/Psalm/Internal/Algebra.php | 113 ++- .../Internal/Algebra/FormulaGenerator.php | 16 +- .../Internal/Analyzer/AlgebraAnalyzer.php | 5 +- .../Statements/Expression/ArrayAnalyzer.php | 2 + .../Statements/Expression/AssertionFinder.php | 677 ++++++++++-------- .../Expression/AssignmentAnalyzer.php | 3 +- .../Expression/BinaryOp/OrAnalyzer.php | 3 +- .../Call/ArrayFunctionArgumentsAnalyzer.php | 6 +- .../Expression/Call/FunctionCallAnalyzer.php | 14 +- .../ExistingAtomicMethodCallAnalyzer.php | 14 +- .../Expression/Call/NewAnalyzer.php | 8 +- .../ExistingAtomicStaticCallAnalyzer.php | 14 +- .../Statements/Expression/CallAnalyzer.php | 244 +++---- .../Expression/Fetch/ArrayFetchAnalyzer.php | 3 +- .../Statements/Expression/TernaryAnalyzer.php | 3 +- src/Psalm/Internal/Clause.php | 66 +- .../Reflector/FunctionLikeDocblockScanner.php | 117 +-- .../Reflector/FunctionLikeNodeScanner.php | 29 +- .../Internal/Provider/NodeDataProvider.php | 19 +- .../ArrayFilterReturnTypeProvider.php | 12 +- .../ArrayMapReturnTypeProvider.php | 5 +- src/Psalm/Internal/Scope/IfScope.php | 3 +- .../Internal/Type/AssertionReconciler.php | 512 ++++++------- .../Type/NegatedAssertionReconciler.php | 212 +++--- .../Type/SimpleAssertionReconciler.php | 540 ++++++++------ .../Type/SimpleNegatedAssertionReconciler.php | 368 +++++----- src/Psalm/Internal/Type/TypeCombination.php | 3 + src/Psalm/Internal/Type/TypeCombiner.php | 39 + src/Psalm/Internal/Type/TypeExpander.php | 3 +- .../Internal/TypeVisitor/TypeChecker.php | 11 - src/Psalm/IssueBuffer.php | 4 +- src/Psalm/Storage/Assertion.php | 110 +-- src/Psalm/Storage/Assertion/Any.php | 25 + .../Assertion/ArrayKeyDoesNotExist.php | 30 + .../Storage/Assertion/ArrayKeyExists.php | 25 + .../Assertion/DoesNotHaveAtLeastCount.php | 40 ++ .../Assertion/DoesNotHaveExactCount.php | 39 + .../Storage/Assertion/DoesNotHaveMethod.php | 37 + src/Psalm/Storage/Assertion/Empty_.php | 30 + src/Psalm/Storage/Assertion/Falsy.php | 30 + src/Psalm/Storage/Assertion/HasArrayKey.php | 33 + .../Storage/Assertion/HasAtLeastCount.php | 34 + src/Psalm/Storage/Assertion/HasExactCount.php | 40 ++ .../Assertion/HasIntOrStringArrayAccess.php | 26 + src/Psalm/Storage/Assertion/HasMethod.php | 32 + .../Assertion/HasStringArrayAccess.php | 26 + src/Psalm/Storage/Assertion/InArray.php | 33 + src/Psalm/Storage/Assertion/IsAClass.php | 45 ++ src/Psalm/Storage/Assertion/IsClassEqual.php | 38 + .../Storage/Assertion/IsClassNotEqual.php | 37 + src/Psalm/Storage/Assertion/IsCountable.php | 25 + src/Psalm/Storage/Assertion/IsEqualIsset.php | 31 + src/Psalm/Storage/Assertion/IsGreaterThan.php | 32 + .../Assertion/IsGreaterThanOrEqualTo.php | 37 + src/Psalm/Storage/Assertion/IsIdentical.php | 50 ++ src/Psalm/Storage/Assertion/IsIsset.php | 25 + src/Psalm/Storage/Assertion/IsLessThan.php | 32 + .../Storage/Assertion/IsLessThanOrEqualTo.php | 37 + .../Storage/Assertion/IsLooselyEqual.php | 50 ++ src/Psalm/Storage/Assertion/IsNotAClass.php | 44 ++ .../Storage/Assertion/IsNotCountable.php | 37 + .../Storage/Assertion/IsNotIdentical.php | 55 ++ src/Psalm/Storage/Assertion/IsNotIsset.php | 30 + .../Storage/Assertion/IsNotLooselyEqual.php | 55 ++ .../Assertion/IsNotPositiveNumeric.php | 30 + src/Psalm/Storage/Assertion/IsNotType.php | 49 ++ .../Storage/Assertion/IsPositiveNumeric.php | 38 + src/Psalm/Storage/Assertion/IsType.php | 44 ++ .../Storage/Assertion/NestedAssertions.php | 38 + src/Psalm/Storage/Assertion/NonEmpty.php | 25 + .../Storage/Assertion/NonEmptyCountable.php | 38 + src/Psalm/Storage/Assertion/NotInArray.php | 38 + .../Storage/Assertion/NotNestedAssertions.php | 43 ++ .../Assertion/NotNonEmptyCountable.php | 30 + src/Psalm/Storage/Assertion/Truthy.php | 25 + src/Psalm/Storage/FunctionLikeStorage.php | 6 +- src/Psalm/Storage/Possibilities.php | 71 ++ src/Psalm/Type/Atomic.php | 8 - src/Psalm/Type/Atomic/TAssertionEmpty.php | 38 - src/Psalm/Type/Atomic/TAssertionFalsy.php | 43 -- src/Psalm/Type/Atomic/TClassString.php | 13 +- src/Psalm/Type/Atomic/TNonEmptyArray.php | 7 +- src/Psalm/Type/Atomic/TNonEmptyList.php | 7 +- src/Psalm/Type/Reconciler.php | 150 ++-- src/Psalm/Type/Union.php | 16 - tests/AlgebraTest.php | 94 ++- tests/ArrayAccessTest.php | 69 ++ tests/ClassLikeStringTest.php | 51 ++ tests/ClassTest.php | 2 +- tests/FunctionCallTest.php | 7 + tests/IntRangeTest.php | 5 +- .../FunctionClassStringTemplateTest.php | 2 +- tests/Template/FunctionTemplateAssertTest.php | 91 ++- tests/TypeReconciliation/EmptyTest.php | 13 - tests/TypeReconciliation/ReconcilerTest.php | 151 ++-- .../RedundantConditionTest.php | 28 + 99 files changed, 3723 insertions(+), 1887 deletions(-) create mode 100644 src/Psalm/Storage/Assertion/Any.php create mode 100644 src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php create mode 100644 src/Psalm/Storage/Assertion/ArrayKeyExists.php create mode 100644 src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php create mode 100644 src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php create mode 100644 src/Psalm/Storage/Assertion/DoesNotHaveMethod.php create mode 100644 src/Psalm/Storage/Assertion/Empty_.php create mode 100644 src/Psalm/Storage/Assertion/Falsy.php create mode 100644 src/Psalm/Storage/Assertion/HasArrayKey.php create mode 100644 src/Psalm/Storage/Assertion/HasAtLeastCount.php create mode 100644 src/Psalm/Storage/Assertion/HasExactCount.php create mode 100644 src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php create mode 100644 src/Psalm/Storage/Assertion/HasMethod.php create mode 100644 src/Psalm/Storage/Assertion/HasStringArrayAccess.php create mode 100644 src/Psalm/Storage/Assertion/InArray.php create mode 100644 src/Psalm/Storage/Assertion/IsAClass.php create mode 100644 src/Psalm/Storage/Assertion/IsClassEqual.php create mode 100644 src/Psalm/Storage/Assertion/IsClassNotEqual.php create mode 100644 src/Psalm/Storage/Assertion/IsCountable.php create mode 100644 src/Psalm/Storage/Assertion/IsEqualIsset.php create mode 100644 src/Psalm/Storage/Assertion/IsGreaterThan.php create mode 100644 src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php create mode 100644 src/Psalm/Storage/Assertion/IsIdentical.php create mode 100644 src/Psalm/Storage/Assertion/IsIsset.php create mode 100644 src/Psalm/Storage/Assertion/IsLessThan.php create mode 100644 src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php create mode 100644 src/Psalm/Storage/Assertion/IsLooselyEqual.php create mode 100644 src/Psalm/Storage/Assertion/IsNotAClass.php create mode 100644 src/Psalm/Storage/Assertion/IsNotCountable.php create mode 100644 src/Psalm/Storage/Assertion/IsNotIdentical.php create mode 100644 src/Psalm/Storage/Assertion/IsNotIsset.php create mode 100644 src/Psalm/Storage/Assertion/IsNotLooselyEqual.php create mode 100644 src/Psalm/Storage/Assertion/IsNotPositiveNumeric.php create mode 100644 src/Psalm/Storage/Assertion/IsNotType.php create mode 100644 src/Psalm/Storage/Assertion/IsPositiveNumeric.php create mode 100644 src/Psalm/Storage/Assertion/IsType.php create mode 100644 src/Psalm/Storage/Assertion/NestedAssertions.php create mode 100644 src/Psalm/Storage/Assertion/NonEmpty.php create mode 100644 src/Psalm/Storage/Assertion/NonEmptyCountable.php create mode 100644 src/Psalm/Storage/Assertion/NotInArray.php create mode 100644 src/Psalm/Storage/Assertion/NotNestedAssertions.php create mode 100644 src/Psalm/Storage/Assertion/NotNonEmptyCountable.php create mode 100644 src/Psalm/Storage/Assertion/Truthy.php create mode 100644 src/Psalm/Storage/Possibilities.php delete mode 100644 src/Psalm/Type/Atomic/TAssertionEmpty.php delete mode 100644 src/Psalm/Type/Atomic/TAssertionFalsy.php diff --git a/phpcs.xml b/phpcs.xml index b1f79cf0c44..7965983c1ee 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -110,6 +110,10 @@ + + src/Psalm/Storage/Assertion/Empty_.php + +