From 09630f081bd8f99abae3ef028f841557c4f7b9bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kucha=C5=99?= <honza.kuchar@grifart.cz>
Date: Mon, 20 Aug 2018 16:26:37 +0200
Subject: [PATCH] simple support for mixed pseudo-type

---
 src/FunctionSignatureAssertionError.php        |  8 ++++++++
 src/SignatureAssertionUtil.php                 | 13 ++++++++++++-
 tests/fn.assertSignature.mixed-pseudotype.phpt | 14 ++++++++++++++
 3 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 tests/fn.assertSignature.mixed-pseudotype.phpt

diff --git a/src/FunctionSignatureAssertionError.php b/src/FunctionSignatureAssertionError.php
index b5d1414..8969048 100644
--- a/src/FunctionSignatureAssertionError.php
+++ b/src/FunctionSignatureAssertionError.php
@@ -91,4 +91,12 @@ final class FunctionSignatureAssertionError extends \AssertionError {
 			"Expected return type of type '$expectedReturnType', but given function declares '$actualReturnType'."
 		);
 	}
+
+	public static function parameterDoesNotAcceptAllRequiredValues(\ReflectionFunction $reflection, \ReflectionType $reflectionType): self
+	{
+		return new self(
+			$reflection,
+			"Parameter of given function does not accept all required values. Parameter restricts input values to {$reflectionType}, assertion requires mixed. (=must accept everything)"
+		);
+	}
 };
diff --git a/src/SignatureAssertionUtil.php b/src/SignatureAssertionUtil.php
index e468c8a..9efb028 100644
--- a/src/SignatureAssertionUtil.php
+++ b/src/SignatureAssertionUtil.php
@@ -55,6 +55,17 @@ final class SignatureAssertionUtil
 	): void
 	{
 		$reflectionType = $parameterReflection->getType();
+		if ($expectedParameterType === 'mixed') {
+			// must accept everything
+			if ($reflectionType === NULL) {
+				return;
+			}
+
+			throw FunctionSignatureAssertionError::parameterDoesNotAcceptAllRequiredValues(
+				$functionReflection,
+				$reflectionType
+			);
+		}
 		assert($reflectionType instanceof \ReflectionType);
 
 		// checks:
@@ -80,7 +91,7 @@ final class SignatureAssertionUtil
 	// Return-type:
 	private static function checkReturnType(?string $expectedReturnType, \ReflectionFunction $reflection): void
 	{
-		if ($expectedReturnType === NULL) {
+		if ($expectedReturnType === NULL || $expectedReturnType === 'mixed') {
 			return;
 		}
 
diff --git a/tests/fn.assertSignature.mixed-pseudotype.phpt b/tests/fn.assertSignature.mixed-pseudotype.phpt
new file mode 100644
index 0000000..913756e
--- /dev/null
+++ b/tests/fn.assertSignature.mixed-pseudotype.phpt
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+namespace MyTestNamespace;
+require __DIR__ . '/bootstrap.php';
+require __DIR__ . '/testClasses.php';
+use function Grifart\AssertFunction\{assertSignature, nullable, params};
+use Grifart\AssertFunction\FunctionSignatureAssertionError;
+use Tester\Assert;
+$place = 'tests/' . basename(__FILE__) . ':' . (__LINE__ +2) . ' ';
+
+$fn = function(string $p1, $p2) {};
+
+assertSignature($fn, params('string', 'mixed'), 'mixed');
+
+Assert::true(true); // if assertion do not fail, we are OK
-- 
GitLab