Skip to content

Commit c1739e6

Browse files
committed
RFC: Counting of non-countable objects, close #354.
1 parent b7ebcbe commit c1739e6

File tree

5 files changed

+76
-2
lines changed

5 files changed

+76
-2
lines changed

jphp-core/tests/org/develnext/jphp/core/compiler/jvm/ArraysTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ public void testArrayReturn() {
9393
Assert.assertEquals(1, memory.toValue(ArrayMemory.class).size());
9494
}
9595

96+
@Test
97+
public void testCountInvalid() {
98+
check("arrays/count_invalid.phpt");
99+
}
100+
96101
@Test
97102
public void testBugs() {
98103
check("arrays/bug148.php");

jphp-core/tests/org/develnext/jphp/core/compiler/jvm/GeneratorsTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ public void testNestedCallsWithDie() {
209209
Assert.assertTrue(false);
210210
}
211211

212+
@Test
213+
public void testCountError() {
214+
check("generators/count_error.phpt");
215+
}
216+
212217
@Test
213218
public void testBug262() {
214219
check("generators/bug262.php");
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Only arrays and countable objects can be counted
3+
--FILE--
4+
<?php
5+
$v = null;
6+
$result = count($v);
7+
var_dump($result);
8+
9+
$v = "string";
10+
$result = count($v);
11+
var_dump($result);
12+
13+
$v = 123;
14+
$result = count($v);
15+
var_dump($result);
16+
17+
$v = true;
18+
$result = count($v);
19+
var_dump($result);
20+
21+
$v = false;
22+
$result = count($v);
23+
var_dump($result);
24+
25+
$result = count((object) []);
26+
var_dump($result);
27+
28+
?>
29+
--EXPECTF--
30+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
31+
int(0)
32+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
33+
int(1)
34+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
35+
int(1)
36+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
37+
int(1)
38+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
39+
int(1)
40+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d
41+
int(1)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Generators can't be counted
3+
--FILE--
4+
<?php
5+
6+
function gen() { yield; }
7+
8+
$gen = gen();
9+
10+
try {
11+
count($gen);
12+
} catch (Exception $e) {
13+
echo $e;
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d at pos %d

jphp-runtime/src/php/runtime/ext/core/ArrayFunctions.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
public class ArrayFunctions extends FunctionsContainer {
1919

20+
public static final String COUNT_WARN_MSG = "count(): Parameter must be an array or an object that implements Countable";
21+
2022
private static int recursive_count(Environment env, TraceInfo trace, ArrayMemory array, Set<Integer> used){
2123
ForeachIterator iterator = array.foreachIterator(false, false);
2224
int size = array.size();
@@ -50,15 +52,16 @@ public static Memory is_countable(Environment env, TraceInfo traceInfo, Memory v
5052
return Memory.FALSE;
5153
}
5254

53-
@Runtime.Immutable
5455
public static Memory count(Environment env, TraceInfo trace, Memory var, int mode){
5556
switch (var.type){
5657
case ARRAY:
5758
if (mode == 1){
5859
return LongMemory.valueOf(recursive_count(env, trace, var.toValue(ArrayMemory.class), null));
5960
} else
6061
return LongMemory.valueOf(var.toValue(ArrayMemory.class).size());
61-
case NULL: return Memory.CONST_INT_0;
62+
case NULL:
63+
env.warning(trace, COUNT_WARN_MSG);
64+
return Memory.CONST_INT_0;
6265
case OBJECT:
6366
ObjectMemory objectMemory = var.toValue(ObjectMemory.class);
6467
if (objectMemory.value instanceof Countable){
@@ -68,9 +71,11 @@ public static Memory count(Environment env, TraceInfo trace, Memory var, int mod
6871
env.forwardThrow(throwable);
6972
}
7073
} else {
74+
env.warning(trace, COUNT_WARN_MSG);
7175
return Memory.CONST_INT_1;
7276
}
7377
default:
78+
env.warning(trace, COUNT_WARN_MSG);
7479
return Memory.CONST_INT_1;
7580
}
7681
}

0 commit comments

Comments
 (0)