diff --git a/src/main/php/lang.base.php b/src/main/php/lang.base.php index 3511328c0..fef176bd3 100755 --- a/src/main/php/lang.base.php +++ b/src/main/php/lang.base.php @@ -159,48 +159,51 @@ function cast($arg, $type) { } // }}} -// {{{ proto bool is(string type, var object) +// {{{ proto bool instance(string type, var value) // Checks whether a given object is an instance of the type given -function is($type, $object) { +function instance($type, $value) { if ('int' === $type) { - return is_int($object); + return is_int($value); } else if ('float' === $type || 'double' === $type) { - return is_float($object); + return is_float($value); } else if ('string' === $type) { - return is_string($object); + return is_string($value); } else if ('bool' === $type) { - return is_bool($object); + return is_bool($value); } else if ('var' === $type) { return true; } else if ('array' === $type) { - return is_array($object); + return is_array($value); } else if ('object' === $type) { - return is_object($object); + return is_object($value); } else if ('callable' === $type) { - return is_callable($object); + return is_callable($value); } else if ('iterable' === $type) { - return is_array($object) || $object instanceof \Traversable; + return is_array($value) || $value instanceof \Traversable; } else if ('?' === $type[0]) { - return null === $object || is(substr($type, 1), $object); + return null === $value || instance(substr($type, 1), $value); } else if (0 === strncmp($type, 'function(', 9)) { - return \lang\FunctionType::forName($type)->isInstance($object); + return \lang\FunctionType::forName($type)->isInstance($value); } else if (0 === substr_compare($type, '[]', -2)) { - return (new \lang\ArrayType(substr($type, 0, -2)))->isInstance($object); + return (new \lang\ArrayType(substr($type, 0, -2)))->isInstance($value); } else if (0 === substr_compare($type, '[:', 0, 2)) { - return (new \lang\MapType(substr($type, 2, -1)))->isInstance($object); + return (new \lang\MapType(substr($type, 2, -1)))->isInstance($value); } else if (0 === strncmp($type, '(function(', 10)) { - return \lang\FunctionType::forName(substr($type, 1, -1))->isInstance($object); + return \lang\FunctionType::forName(substr($type, 1, -1))->isInstance($value); } else if (strstr($type, '|')) { - return \lang\TypeUnion::forName($type)->isInstance($object); + return \lang\TypeUnion::forName($type)->isInstance($value); } else if (strstr($type, '&')) { - return \lang\TypeIntersection::forName($type)->isInstance($object); + return \lang\TypeIntersection::forName($type)->isInstance($value); } else if (strstr($type, '?')) { - return \lang\WildcardType::forName($type)->isInstance($object); + return \lang\WildcardType::forName($type)->isInstance($value); } else { $literal= literal($type); - return $object instanceof $literal; + return $value instanceof $literal; } } + +// Deprecated alias +function is($type, $object) { return instance($type, $object); } // }}} // {{{ proto string literal(string type) diff --git a/src/main/php/lang/GenericTypes.class.php b/src/main/php/lang/GenericTypes.class.php index ee3d039aa..f4b52b855 100755 --- a/src/main/php/lang/GenericTypes.class.php +++ b/src/main/php/lang/GenericTypes.class.php @@ -256,22 +256,18 @@ public function newType0($base, $arguments) { if (null === $type) { continue; } else if ('...' === substr($type, -3)) { - $src.= $j ? '$ˇargs= array_slice(func_get_args(), '.$j.');' : '$ˇargs= func_get_args();'; - $src.= ( - ' if (!is(\''.substr($generic[$j], 0, -3).'[]\', $ˇargs)) throw new \lang\IllegalArgumentException('. - '"Vararg '.($j + 1).' passed to ".__METHOD__."'. - ' must be of '.$type.', ".typeof($ˇargs)->getName()." given"'. - ');' - ); + $verify= substr($generic[$j], 0, -3).'[]'; } else { - $src.= ( - ' if ('.(isset($default[$j]) ? '('.$default[$j].' !== '.$parameters[$j].') && ' : ''). - '!is(\''.$generic[$j].'\', '.$parameters[$j].')) throw new \lang\IllegalArgumentException('. - '"Argument '.($j + 1).' passed to ".__METHOD__."'. - ' must be of '.$type.', ".typeof('.$parameters[$j].')->getName()." given"'. - ');' - ); + $verify= $generic[$j]; } + + $src.= ( + ' if ('.(isset($default[$j]) ? '('.$default[$j].' !== '.$parameters[$j].') && ' : ''). + '!instance(\''.$verify.'\', '.$parameters[$j].')) throw new \lang\IllegalArgumentException('. + '"Argument '.($j + 1).' passed to ".__METHOD__."'. + ' must be of '.$type.', ".typeof('.$parameters[$j].')." given"'. + ');' + ); } } continue; @@ -326,7 +322,7 @@ public function newType0($base, $arguments) { } // Create class - // DEBUG fputs(STDERR, "@* ".substr($src, 0, strpos($src, '{'))." -> $qname\n"); + // fputs(STDERR, "@* ".substr($src, 0, strpos($src, '{'))." -> $qname\n"); eval($src); if ($initialize) { foreach ($components as $i => $component) { diff --git a/src/main/php/lang/XPClass.class.php b/src/main/php/lang/XPClass.class.php index 75ea1bd52..9bf743725 100755 --- a/src/main/php/lang/XPClass.class.php +++ b/src/main/php/lang/XPClass.class.php @@ -203,7 +203,7 @@ public function isAssignableFrom($type): bool { /** * Determines whether the specified object is an instance of this - * class. This is the equivalent of the `is()` core functionality. + * class. This is the equivalent of the `instance()` core functionality. * * ```php * $class= XPClass::forName('io.File'); @@ -217,7 +217,7 @@ public function isAssignableFrom($type): bool { * @return bool */ public function isInstance($obj): bool { - return is($this->name, $obj); + return $obj instanceof $this->_class; } /** Retrieve the class loader a class was loaded with */ diff --git a/src/test/php/lang/unittest/IsTest.class.php b/src/test/php/lang/unittest/InstanceTest.class.php similarity index 65% rename from src/test/php/lang/unittest/IsTest.class.php rename to src/test/php/lang/unittest/InstanceTest.class.php index 05367abb8..664376f39 100755 --- a/src/test/php/lang/unittest/IsTest.class.php +++ b/src/test/php/lang/unittest/InstanceTest.class.php @@ -4,7 +4,7 @@ use lang\{ClassLoader, Runnable}; use test\{Assert, Test, Values}; -class IsTest { +class InstanceTest { /** @return iterable */ private function callables() { @@ -39,128 +39,128 @@ private function functions() { #[Test] public function string_array() { - Assert::true(is('string[]', ['Hello'])); + Assert::true(instance('string[]', ['Hello'])); } #[Test] public function var_array() { - Assert::false(is('string[]', ['Hello', 1, true])); + Assert::false(instance('string[]', ['Hello', 1, true])); } #[Test] public function int_array() { - Assert::true(is('int[]', [1, 2, 3])); + Assert::true(instance('int[]', [1, 2, 3])); } #[Test] public function mapIsNotAnInt_array() { - Assert::false(is('int[]', ['one' => 1, 'two' => 2])); + Assert::false(instance('int[]', ['one' => 1, 'two' => 2])); } #[Test] public function intIsNotAnInt_array() { - Assert::false(is('int[]', 1)); + Assert::false(instance('int[]', 1)); } #[Test] public function thisIsNotAnInt_array() { - Assert::false(is('int[]', $this)); + Assert::false(instance('int[]', $this)); } #[Test] public function emptyArrayIsAnInt_array() { - Assert::true(is('int[]', [])); + Assert::true(instance('int[]', [])); } #[Test] public function object_array() { - Assert::true(is('lang.unittest.Name[]', [new Name('test'), new Name('test'), new Name('test')])); + Assert::true(instance('lang.unittest.Name[]', [new Name('test'), new Name('test'), new Name('test')])); } #[Test] public function objectArrayWithnull() { - Assert::false(is('lang.unittest.Name[]', [new Name('test'), new Name('test'), null])); + Assert::false(instance('lang.unittest.Name[]', [new Name('test'), new Name('test'), null])); } #[Test] public function stringMap() { - Assert::true(is('[:string]', ['greet' => 'Hello', 'whom' => 'World'])); + Assert::true(instance('[:string]', ['greet' => 'Hello', 'whom' => 'World'])); } #[Test] public function intMap() { - Assert::true(is('[:int]', ['greet' => 1, 'whom' => 2])); + Assert::true(instance('[:int]', ['greet' => 1, 'whom' => 2])); } #[Test] public function intArrayIsNotAnIntMap() { - Assert::false(is('[:int]', [1, 2, 3])); + Assert::false(instance('[:int]', [1, 2, 3])); } #[Test] public function intIsNotAnIntMap() { - Assert::false(is('[:int]', 1)); + Assert::false(instance('[:int]', 1)); } #[Test] public function thisIsNotAnIntMap() { - Assert::false(is('[:int]', $this)); + Assert::false(instance('[:int]', $this)); } #[Test] public function emptyArrayIsAnIntMap() { - Assert::true(is('[:int]', [])); + Assert::true(instance('[:int]', [])); } #[Test] public function stringPrimitive() { - Assert::true(is('string', 'Hello')); + Assert::true(instance('string', 'Hello')); } #[Test] public function nullNotAStringPrimitive() { - Assert::false(is('string', null)); + Assert::false(instance('string', null)); } #[Test] public function boolPrimitive() { - Assert::true(is('bool', true)); + Assert::true(instance('bool', true)); } #[Test] public function nullNotABoolPrimitive() { - Assert::false(is('bool', null)); + Assert::false(instance('bool', null)); } #[Test] public function doublePrimitive() { - Assert::true(is('double', 0.0)); + Assert::true(instance('double', 0.0)); } #[Test] public function nullNotADoublePrimitive() { - Assert::false(is('double', null)); + Assert::false(instance('double', null)); } #[Test] public function intPrimitive() { - Assert::true(is('int', 0)); + Assert::true(instance('int', 0)); } #[Test] public function nullNotAnIntPrimitive() { - Assert::false(is('int', null)); + Assert::false(instance('int', null)); } #[Test] public function undefinedClassName() { Assert::false(class_exists('Undefined_Class', false)); - Assert::false(is('Undefined_Class', new class() { })); + Assert::false(instance('Undefined_Class', new class() { })); } #[Test] public function fullyQualifiedClassName() { - Assert::true(is('lang.Value', new Name('test'))); + Assert::true(instance('lang.Value', new Name('test'))); } #[Test] @@ -178,24 +178,24 @@ public function interfaces() { [] ); - Assert::true(is('lang.Runnable', new RunnableImpl())); - Assert::true(is('lang.Runnable', new RunnableImplEx())); - Assert::false(is('lang.Runnable', new class() { })); + Assert::true(instance('lang.Runnable', new RunnableImpl())); + Assert::true(instance('lang.Runnable', new RunnableImplEx())); + Assert::false(instance('lang.Runnable', new class() { })); } #[Test] public function aStringVectorIsIsItself() { - Assert::true(is('lang.unittest.ListOf', create('new lang.unittest.ListOf'))); + Assert::true(instance('lang.unittest.ListOf', create('new lang.unittest.ListOf'))); } #[Test] public function aVectorIsNotAStringVector() { - Assert::false(is('lang.unittest.ListOf', new ListOf())); + Assert::false(instance('lang.unittest.ListOf', new ListOf())); } #[Test] public function aStringVectorIsNotAVector() { - Assert::false(is( + Assert::false(instance( 'lang.unittest.ListOf', create('new lang.unittest.ListOf') )); @@ -203,7 +203,7 @@ public function aStringVectorIsNotAVector() { #[Test] public function anIntVectorIsNotAStringVector() { - Assert::false(is( + Assert::false(instance( 'lang.unittest.ListOf', create('new lang.unittest.ListOf') )); @@ -211,7 +211,7 @@ public function anIntVectorIsNotAStringVector() { #[Test] public function aVectorOfIntVectorsIsItself() { - Assert::true(is( + Assert::true(instance( 'lang.unittest.ListOf>', create('new lang.unittest.ListOf>') )); @@ -219,7 +219,7 @@ public function aVectorOfIntVectorsIsItself() { #[Test] public function aVectorOfIntVectorsIsNotAVectorOfStringVectors() { - Assert::false(is( + Assert::false(instance( 'lang.unittest.ListOf>', create('new lang.unittest.ListOf>') )); @@ -227,7 +227,7 @@ public function aVectorOfIntVectorsIsNotAVectorOfStringVectors() { #[Test] public function anIntVectorIsNotAnUndefinedGeneric() { - Assert::false(is('Undefined_Class', create('new lang.unittest.ListOf'))); + Assert::false(instance('Undefined_Class', create('new lang.unittest.ListOf'))); } /** @return var[][] */ @@ -241,17 +241,17 @@ private function genericDictionaries() { #[Test, Values(from: 'genericDictionaries')] public function wildcard_check_for_type_parameters($value) { - Assert::true(is('lang.unittest.Lookup', $value)); + Assert::true(instance('lang.unittest.Lookup', $value)); } #[Test, Values(from: 'genericDictionaries')] public function wildcard_check_for_type_parameter_with_super_type($value) { - Assert::true(is('lang.unittest.IDictionary', $value)); + Assert::true(instance('lang.unittest.IDictionary', $value)); } #[Test] public function wildcard_check_for_single_type_parameter_generic() { - Assert::true(is( + Assert::true(instance( 'lang.unittest.ListOf>', create('new lang.unittest.ListOf>') )); @@ -259,7 +259,7 @@ public function wildcard_check_for_single_type_parameter_generic() { #[Test] public function wildcard_check_for_type_parameters_partial() { - Assert::true(is( + Assert::true(instance( 'lang.unittest.Lookup', create('new lang.unittest.Lookup') )); @@ -267,68 +267,68 @@ public function wildcard_check_for_type_parameters_partial() { #[Test] public function wildcard_check_for_newinstance() { - Assert::true(is('util.Filter', newinstance('util.Filter', [], [ + Assert::true(instance('util.Filter', newinstance('util.Filter', [], [ 'accept' => fn($e) => true ]))); } #[Test] public function function_type() { - Assert::true(is('function(): var', function() { })); + Assert::true(instance('function(): var', function() { })); } #[Test] public function function_type_returning_array() { - Assert::true(is('function(): var[]', function() { })); + Assert::true(instance('function(): var[]', function() { })); } #[Test] public function braced_function_type() { - Assert::true(is('(function(): var)', function() { })); + Assert::true(instance('(function(): var)', function() { })); } #[Test] public function array_of_function_type() { - Assert::true(is('(function(): var)[]', [function() { }])); + Assert::true(instance('(function(): var)[]', [function() { }])); } #[Test, Values([1, 'Test'])] public function type_union($val) { - Assert::true(is('int|string', $val)); + Assert::true(instance('int|string', $val)); } #[Test, Values([1, null])] public function nullable($val) { - Assert::true(is('?int', $val)); + Assert::true(instance('?int', $val)); } #[Test, Values(from: 'callables')] public function is_callable($val) { - Assert::true(is('callable', $val)); + Assert::true(instance('callable', $val)); } #[Test, Values([[[]], [[1, 2, 3]], [['key' => 'value']],])] public function is_array($val) { - Assert::true(is('array', $val)); + Assert::true(instance('array', $val)); } #[Test, Values(from: 'iterables')] public function is_iterable($val) { - Assert::true(is('iterable', $val)); + Assert::true(instance('iterable', $val)); } #[Test, Values(from: 'objects')] public function is_object($val) { - Assert::true(is('object', $val)); + Assert::true(instance('object', $val)); } #[Test, Values(from: 'functions')] public function closures_are_objects($val) { - Assert::true(is('object', $val)); + Assert::true(instance('object', $val)); } #[Test] public function type_intersection() { - Assert::true(is('Countable&Traversable', new \ArrayObject([]))); + Assert::true(instance('Countable&Traversable', new \ArrayObject([]))); } } \ No newline at end of file