jenkins-bot has submitted this change and it was merged.
Change subject: Add Array Functions (version 0.4.1)
......................................................................
Add Array Functions (version 0.4.1)
* Fix variable name in DebugView
Change-Id: Iad8f88d971c7d4494a404a6bcd9709f3a948e242
---
M Foxway.body.php
M Foxway.php
M includes/Interpreter.php
M includes/ROutput.php
M includes/RValue.php
M includes/Runtime.php
M includes/RuntimeDebug.php
M includes/functions/BaseFunction.php
A includes/functions/FArray.php
M includes/functions/FVariable.php
M tests/phpunit/includes/InterpreterTest.php
11 files changed, 281 insertions(+), 15 deletions(-)
Approvals:
Pastakhov: Looks good to me, approved
jenkins-bot: Verified
diff --git a/Foxway.body.php b/Foxway.body.php
index fd74dd6..0013902 100644
--- a/Foxway.body.php
+++ b/Foxway.body.php
@@ -94,7 +94,7 @@
}
private static function getScope(PPFrame $frame) {
- foreach (self::$frames as $value) {
+ foreach (self::$frames as &$value) {
if( $value[0] === $frame ) {
return $value[1];
}
diff --git a/Foxway.php b/Foxway.php
index 27f3229..2ddd4b0 100644
--- a/Foxway.php
+++ b/Foxway.php
@@ -15,7 +15,7 @@
die( 'This file is an extension to MediaWiki and thus not a valid entry
point.' );
}
-define( 'Foxway_VERSION' , '0.4.0' );
+define( 'Foxway_VERSION' , '0.4.1' );
// Register this extension on Special:Version
$wgExtensionCredits['parserhook'][] = array(
@@ -63,6 +63,7 @@
$wgAutoloadClasses['Foxway\\RuntimeDebug'] = $dir .
'/includes/RuntimeDebug.php';
$wgAutoloadClasses['Foxway\\BaseFunction'] = $dir .
'/includes/functions/BaseFunction.php';
+$wgAutoloadClasses['Foxway\\FArray'] = $dir .
'/includes/functions/FArray.php';
$wgAutoloadClasses['Foxway\\FVariable'] = $dir .
'/includes/functions/FVariable.php';
// Resources
@@ -87,10 +88,33 @@
$wgFoxwayPassByReference = array(
'settype' => 1,
'unset' => -1,
+ 'array_multisort' => -1,
+ 'array_pop' => 1,
+ 'array_push' => 1,
+ 'array_shift' => 1,
+ 'array_splice' => 1,
+ 'array_unshift' => 1,
+ 'arsort' => 1,
+ 'asort' => 1,
+ 'current' => 1,
+ 'each' => 1,
+ 'end' => 1,
+ 'key' => 1,
+ 'krsort' => 1,
+ 'ksort' => 1,
+ 'natcasesort' => 1,
+ 'natsort' => 1,
+ 'next' => 1,
+ 'pos' => 1,
+ 'prev' => 1,
+ 'reset' => 1,
+ 'rsort' => 1,
+ 'shuffle' => 1,
+ 'sort' => 1,
);
$wgFoxwayFunctions = array(
- 'FVariable' => array( // @see http://www.php.net/manual/en/ref.var.php
+ 'FVariable' => array( // Variable handling Functions @see
http://www.php.net/manual/en/ref.var.php
'boolval',
//'debug_zval_dump',
'doubleval',
@@ -126,4 +150,62 @@
'var_dump',
'var_export',
),
+ 'FArray' => array( // Array Functions @see
http://www.php.net/manual/en/ref.array.php
+ 'array_change_key_case',
+ 'array_chunk',
+ //'array_column', @todo PHP 5 >= 5.5.0
+ 'array_combine',
+ 'array_count_values',
+ 'array_diff_assoc',
+ 'array_diff_key',
+ 'array_diff',
+ 'array_fill_keys',
+ 'array_fill',
+ 'array_flip',
+ 'array_intersect_assoc',
+ 'array_intersect_key',
+ 'array_intersect',
+ 'array_key_exists',
+ 'array_keys',
+ 'array_merge_recursive',
+ 'array_merge',
+ 'array_multisort',
+ 'array_pad',
+ 'array_pop',
+ 'array_product',
+ 'array_push',
+ 'array_rand',
+ 'array_replace_recursive',
+ 'array_replace',
+ 'array_reverse',
+ 'array_search',
+ 'array_shift',
+ 'array_slice',
+ 'array_splice',
+ 'array_sum',
+ 'array_unique',
+ 'array_unshift',
+ 'array_values',
+ 'arsort',
+ 'asort',
+ 'count',
+ 'current',
+ 'each',
+ 'end',
+ 'in_array',
+ 'key',
+ 'krsort',
+ 'ksort',
+ 'natcasesort',
+ 'natsort',
+ 'next',
+ 'pos',
+ 'prev',
+ 'range',
+ 'reset',
+ 'rsort',
+ 'shuffle',
+ 'sizeof',
+ 'sort',
+ ),
);
diff --git a/includes/Interpreter.php b/includes/Interpreter.php
index e9e3fc3..57f0955 100644
--- a/includes/Interpreter.php
+++ b/includes/Interpreter.php
@@ -403,6 +403,8 @@
$debug[] = $token;
}
continue 2;
+ } elseif(
isset(self::$PHPConstants[$text]) ) {
+ $runtime->addParamValue(
self::$PHPConstants[$text] );
} else {
$return[] = new
ErrorMessage(__LINE__, $tokenLine, E_PARSE, $id);
break 2;
@@ -959,4 +961,18 @@
return (float)( substr($string, 0, $epos) * pow(10,
substr($string, $epos+1)) );
}
+ private static $PHPConstants = array(
+ 'CASE_UPPER' => CASE_UPPER,
+ 'CASE_LOWER' => CASE_LOWER,
+ 'SORT_ASC' => SORT_ASC,
+ 'SORT_DESC' => SORT_DESC,
+ 'SORT_REGULAR' => SORT_REGULAR,
+ 'SORT_NUMERIC' => SORT_NUMERIC,
+ 'SORT_STRING' => SORT_STRING,
+ 'SORT_LOCALE_STRING' => SORT_LOCALE_STRING,
+ //'SORT_NATURAL' => SORT_NATURAL, // @todo PHP >= 5.4.0
+ //'SORT_FLAG_CASE' => SORT_FLAG_CASE, // @todo PHP >= 5.4.0
+ 'COUNT_RECURSIVE' => COUNT_RECURSIVE,
+ );
+
}
diff --git a/includes/ROutput.php b/includes/ROutput.php
index 2722e54..1bb726c 100644
--- a/includes/ROutput.php
+++ b/includes/ROutput.php
@@ -23,6 +23,6 @@
if( $this->element !== null ){
return \Html::element( $this->element, array(),
$this->string ) . "\n";
}
- return $this->string . "\n";
+ return strtr( $this->string, array('&'=>'&', '<'=>'<') )
. "\n";
}
}
diff --git a/includes/RValue.php b/includes/RValue.php
index 12cc1f9..03884f4 100644
--- a/includes/RValue.php
+++ b/includes/RValue.php
@@ -23,4 +23,8 @@
$this->value = $value;
}
+ public function getReference() {
+ return $this->value;
+ }
+
}
diff --git a/includes/Runtime.php b/includes/Runtime.php
index f6d1a9c..564bb39 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -80,7 +80,7 @@
public function getOperators() {
static $operators = array();
if( count($operators) == 0 ) {
- foreach (self::$operatorsPrecedence as $value) {
+ foreach (self::$operatorsPrecedence as &$value) {
$operators = array_merge($operators, $value);
}
}
@@ -89,7 +89,7 @@
protected function getOperatorPrecedence( $operator ) {
$precendence = 0;
- foreach (self::$operatorsPrecedence as $operators) {
+ foreach (self::$operatorsPrecedence as &$operators) {
if( in_array($operator, $operators) ) {
break;
}
@@ -504,6 +504,7 @@
$functionName = "f_{$this->lastCommand}";
$functionClass = 'Foxway\\' .
Interpreter::getClassNameForFunction($this->lastCommand);
+ // @todo check for $functionClass is exists class
$class = new \ReflectionClass($functionClass);
if( $class->isSubclassOf("Foxway\\BaseFunction") ) {
try {
diff --git a/includes/RuntimeDebug.php b/includes/RuntimeDebug.php
index d8dfc1c..a6e66f5 100644
--- a/includes/RuntimeDebug.php
+++ b/includes/RuntimeDebug.php
@@ -58,11 +58,11 @@
if( $operator == '=' ) {
if( $param instanceof RArray ) {
$i = $param->getIndex();
- $return = \Html::element( 'span',
array('class'=>'foxway_variable'), $param->getParent()->getName() ) .
+ $return = \Html::element( 'span',
array('class'=>'foxway_variable'), '$'.$param->getParent()->getName() ) .
( $i instanceof RValue ?
'['.self::getHTMLForValue($i).']' : '[]' ) .
' <b>=></b> = ';
}else{
- $return = \Html::element( 'span',
array('class'=>'foxway_variable'), $param->getName() ) .
+ $return = \Html::element( 'span',
array('class'=>'foxway_variable'), '$'.$param->getName() ) .
' <b>=></b> = ';
}
} else {
@@ -157,7 +157,7 @@
$class = 'foxway_number';
break;
case 'array': // @todo normalize it
- if( count($value) <= 3 ) {
+ if( count($value, COUNT_RECURSIVE) <= 3 ) {
$value = var_export($value, true);
} else {
$value = 'array';
@@ -185,11 +185,11 @@
$param = $param->getParent();
} while ( $param instanceof RArray );
return ($param->is_set() ? '' : \Html::element( 'span',
array('class'=>'foxway_undefined'), "Undefined " ) ) .
- \Html::element( 'span',
array('class'=>'foxway_variable'), $param->getName() ) .
+ \Html::element( 'span',
array('class'=>'foxway_variable'), '$'.$param->getName() ) .
implode('', $indexes) . "($value)";
} elseif( $param instanceof RVariable ) {
return ($param->is_set() ? '' : \Html::element( 'span',
array('class'=>'foxway_undefined'), "Undefined " ) ) .
- \Html::element( 'span',
array('class'=>'foxway_variable'), $param->getName() ) . "($value)";
+ \Html::element( 'span',
array('class'=>'foxway_variable'), '$'.$param->getName() ) . "($value)";
}
return $value;
}
diff --git a/includes/functions/BaseFunction.php
b/includes/functions/BaseFunction.php
index 2cfdb41..e5bea8b 100644
--- a/includes/functions/BaseFunction.php
+++ b/includes/functions/BaseFunction.php
@@ -1,5 +1,7 @@
<?php
namespace Foxway;
+define('FOXWAY_MAX_PAST_PARAM', 16);
+
/**
* BaseFunction base class for functions classes of Foxway extension.
*
diff --git a/includes/functions/FArray.php b/includes/functions/FArray.php
new file mode 100644
index 0000000..154e2f7
--- /dev/null
+++ b/includes/functions/FArray.php
@@ -0,0 +1,112 @@
+<?php
+namespace Foxway;
+/**
+ * FArray class implements Array Functions for Foxway extension.
+ *
+ * @file FArray.php
+ * @ingroup Foxway
+ * @author Pavel Astakhov <[email protected]>
+ * @licence GNU General Public Licence 2.0 or later
+ */
+class FArray extends BaseFunction {
+ protected static $listFunction = array(
+ 'f_array_change_key_case' => array('array_change_key_case', 1,
2),
+ 'f_array_chunk' => array('array_chunk', 2, 3),
+ //'f_array_column' => array('array_column', 2, 3), @todo PHP 5
>= 5.5.0
+ 'f_array_combine' => array('array_combine', 2, 2),
+ 'f_array_count_values' => array('array_count_values', 1, 1),
+ 'f_array_diff_assoc' => array('array_diff_assoc', 2,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_diff_key' => array('array_diff_key', 2,
FOXWAY_MAX_PAST_PARAM),
+ // @todo array_diff_uassoc
+ // @todo array_diff_ukey
+ 'f_array_diff' => array('array_diff', 2, FOXWAY_MAX_PAST_PARAM),
+ 'f_array_fill_keys' => array('array_fill_keys', 2, 2),
+ 'f_array_fill' => array('array_fill', 3, 3),
+ // @todo array_filter
+ 'f_array_flip' => array('array_flip', 1, 1),
+ 'f_array_intersect_assoc' => array('array_intersect_assoc', 2,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_intersect_key' => array('array_intersect_key', 2,
FOXWAY_MAX_PAST_PARAM),
+ // @todo array_intersect_uassoc
+ // @todo array_intersect_ukey
+ 'f_array_intersect' => array('array_intersect', 2,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_key_exists' => array('array_key_exists', 2, 2),
+ 'f_array_keys' => array('array_keys', 1, 3),
+ // @todo array_map
+ 'f_array_merge_recursive' => array('array_merge_recursive', 1,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_merge' => array('array_merge', 1,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_multisort' => array('array_multisort', 1,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_pad' => array('array_pad', 3, 3),
+ 'f_array_pop' => array('array_pop', 1, 1),
+ 'f_array_product' => array('array_product', 1, 1),
+ 'f_array_push' => array('array_push', 2, FOXWAY_MAX_PAST_PARAM),
+ 'f_array_rand' => array('array_rand', 1, 2),
+ // @todo array_reduce
+ 'f_array_replace_recursive' => array('array_replace_recursive',
2, FOXWAY_MAX_PAST_PARAM),
+ 'f_array_replace' => array('array_replace', 2,
FOXWAY_MAX_PAST_PARAM),
+ 'f_array_reverse' => array('array_reverse', 1, 2),
+ 'f_array_search' => array('array_search', 2, 3),
+ 'f_array_shift' => array('array_shift', 1, 1),
+ 'f_array_slice' => array('array_slice', 2, 4),
+ 'f_array_splice' => array('array_splice', 2, 4),
+ 'f_array_sum' => array('array_sum', 1, 1),
+ // @todo array_udiff_assoc
+ // @todo array_udiff_uassoc
+ // @todo array_udiff
+ // @todo array_uintersect_assoc
+ // @todo array_uintersect_uassoc
+ // @todo array_uintersect
+ 'f_array_unique' => array('array_unique', 1, 2),
+ 'f_array_unshift' => array('array_unshift', 2, 3),
+ 'f_array_values' => array('array_values', 1, 1),
+ //@todo array_walk_recursive
+ //@todo array_walk
+ 'f_arsort' => array('arsort', 1, 2),
+ 'f_asort' => array('asort', 1, 2),
+ // @todo compact
+ 'f_count' => array('count', 1, 2),
+ 'f_current' => array('current', 1, 1),
+ 'f_each' => array('each', 1, 1),
+ 'f_end' => array('end', 1, 1),
+ // @todo extract
+ 'f_in_array' => array('in_array', 2, 3),
+ 'f_key' => array('key', 1, 1),
+ 'f_krsort' => array('krsort', 1, 2),
+ 'f_ksort' => array('ksort', 1, 2),
+ // @todo list
+ 'f_natcasesort' => array('natcasesort', 1, 1),
+ 'f_natsort' => array('natsort', 1, 1),
+ 'f_next' => array('next', 1, 1),
+ 'f_pos' => array('current', 1, 1), // Alias of current()
+ 'f_prev' => array('prev', 1, 1),
+ 'f_range' => array('range', 2, 3),
+ 'f_reset' => array('reset', 1, 1),
+ 'f_rsort' => array('rsort', 1, 2),
+ 'f_shuffle' => array('shuffle', 1, 1),
+ 'f_sizeof' => array('count', 1, 2), //Alias of count()
+ 'f_sort' => array('sort', 1, 2),
+ // @todo uasort
+ // @todo uksort
+ // @todo usort
+ );
+
+ public static function __callStatic($name, $arguments) {
+ if( isset(self::$listFunction[$name]) ) {
+ $funcData = &self::$listFunction[$name];
+ $refarg = &$arguments[0];
+ foreach ($refarg as $key => &$value) {
+ if( $value instanceof RValue ) {
+ $refarg[$key] = &$value->getReference();
+ }
+ }
+ $c = count($refarg);
+ if( $c >= $funcData[1] && $c <= $funcData[2] ) {
+ return new RValue(
call_user_func_array($funcData[0], $refarg) );
+ }else{
+ return self::wrongParameterCount($name,
__LINE__);
+ }
+ } else {
+ return self::callUnknownMethod($name, __LINE__);
+ }
+ }
+
+}
diff --git a/includes/functions/FVariable.php b/includes/functions/FVariable.php
index 4dc0d3d..33f3d58 100644
--- a/includes/functions/FVariable.php
+++ b/includes/functions/FVariable.php
@@ -28,8 +28,8 @@
class FVariable extends BaseFunction {
public static function __callStatic($name, $arguments) {
- if( count($arguments) != 1 ) {
- return self::wrongParameterCount(__FUNCTION__,
__LINE__);
+ if( count($arguments[0]) != 1 ) {
+ return self::wrongParameterCount($name, __LINE__);
}
$arg = &$arguments[0][0];
@@ -79,7 +79,7 @@
$return = strval($arg);
break;
default:
- return self::callUnknownMethod(__FUNCTION__,
__LINE__);
+ return parent::__callStatic($name, __LINE__);
break;
}
return new RValue($return);
@@ -112,7 +112,7 @@
* @return \Foxway\RValue
*/
public static function f_isset($arguments) {
- foreach ( $arguments as $value ) {
+ foreach ( $arguments as &$value ) {
if( $value === null ) {
return new RValue(false);
}
diff --git a/tests/phpunit/includes/InterpreterTest.php
b/tests/phpunit/includes/InterpreterTest.php
index bd63f28..cddfa50 100644
--- a/tests/phpunit/includes/InterpreterTest.php
+++ b/tests/phpunit/includes/InterpreterTest.php
@@ -1946,6 +1946,55 @@
);
}
+ public function testRun_RArray_count() {
+ $this->assertEquals(
+ Interpreter::run('$transport = array("foot",
"bike", "car", "plane"); echo count($transport);'),
+ array('4')
+ );
+ }
+ public function testRun_RArray_current() {
+ $this->assertEquals(
+ Interpreter::run('echo current($transport);'),
+ array('foot')
+ );
+ }
+ public function testRun_RArray_next() {
+ $this->assertEquals(
+ Interpreter::run('echo next($transport),
next($transport);'),
+ array('bike', 'car')
+ );
+ }
+ public function testRun_RArray_end() {
+ $this->assertEquals(
+ Interpreter::run('echo end($transport);'),
+ array('plane')
+ );
+ }
+ public function testRun_RArray_prev() {
+ $this->assertEquals(
+ Interpreter::run('echo prev($transport),
prev($transport);'),
+ array('car', 'bike')
+ );
+ }
+ public function testRun_RArray_each() {
+ $this->assertEquals(
+ Interpreter::run('$foo = each($transport); echo
$foo[0], $foo[1];'),
+ array('1', 'bike')
+ );
+ }
+ public function testRun_RArray_key() {
+ $this->assertEquals(
+ Interpreter::run('echo key($transport);'),
+ array('2')
+ );
+ }
+ public function testRun_RArray_in_array_1() {
+ $this->assertEquals(
+ Interpreter::run('echo in_array("bike",
$transport);'),
+ array('1')
+ );
+ }
+
}
// @todo echo is_scalar(array("foo","bar") ? "true" : "false"; // most return
error
--
To view, visit https://gerrit.wikimedia.org/r/67242
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Iad8f88d971c7d4494a404a6bcd9709f3a948e242
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/Foxway
Gerrit-Branch: master
Gerrit-Owner: Pastakhov <[email protected]>
Gerrit-Reviewer: Pastakhov <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits