Allow .hhas to specify default values

It only matters for reflection, but hhas parameters with
default values need to specify the text of the string.

In addition, change reflection to report parameters with no
default value string as not having a default value, to avoid
crashing when trying to access it.

Update the "func" parameter of array_filter to have a valid
default. The other uses of defaults in array_map and array_filter
are just to get the proper behavior on too few/too many args,
and don't really correspond to default values.
Esse commit está contido em:
mwilliams
2013-06-26 14:34:28 -07:00
commit de Sara Golemon
commit 0632fb3a11
5 arquivos alterados com 61 adições e 14 exclusões
+2 -1
Ver Arquivo
@@ -439,7 +439,8 @@ static void set_function_info(Array &ret, const Func* func) {
param.set(s_nullable, true_varNR);
}
if (fpi.hasDefaultValue()) {
if (fpi.phpCode()) {
assert(fpi.hasDefaultValue());
if (fpi.hasScalarDefaultValue()) {
// Most of the time the default value is scalar, so we can
// avoid evaling in the common case
+45 -12
Ver Arquivo
@@ -1118,16 +1118,12 @@ struct Initializer {
//////////////////////////////////////////////////////////////////////
/*
* php-serialized : long-string-literal
* ;
* long-string-literal: <string>
*
* `long-string-literal' is a python-style longstring. See
* readLongString for more details.
*
* Returns a Variant representing the serialized data. It's up to the
* caller to make sure it is a legal literal.
*/
Variant parse_php_serialized(AsmState& as) {
String parse_long_string(AsmState& as) {
as.in.skipWhitespace();
std::vector<char> buffer;
@@ -1141,8 +1137,21 @@ Variant parse_php_serialized(AsmState& as) {
// String wants a null, and dereferences one past the size we give
// it.
buffer.push_back('\0');
String data(&buffer[0], buffer.size() - 1, AttachLiteral);
return unserialize_from_string(data);
return String(&buffer[0], buffer.size() - 1, AttachLiteral);
}
/*
* php-serialized : long-string-literal
* ;
*
* `long-string-literal' is a python-style longstring. See
* readLongString for more details.
*
* Returns a Variant representing the serialized data. It's up to the
* caller to make sure it is a legal literal.
*/
Variant parse_php_serialized(AsmState& as) {
return unserialize_from_string(parse_long_string(as));
}
/*
@@ -1369,8 +1378,12 @@ Attr parse_attribute_list(AsmState& as, AttrContext ctx) {
* ;
*
* dv-initializer : empty
* | '=' identifier
* | '=' identifier arg-default
* ;
*
* arg-default : empty
* | '(' long-string-literal ')'
* ;
*/
void parse_parameter_list(AsmState& as) {
as.in.skipWhitespace();
@@ -1396,8 +1409,6 @@ void parse_parameter_list(AsmState& as) {
as.error("expected parameter name after $");
}
as.fe->appendParam(StringData::GetStaticString(name), param);
as.in.skipWhitespace();
ch = as.in.getc();
if (ch == '=') {
@@ -1407,9 +1418,29 @@ void parse_parameter_list(AsmState& as) {
if (!as.in.readword(label)) {
as.error("expected label name for dv-initializer");
}
as.addLabelDVInit(label, as.fe->numParams() - 1);
as.addLabelDVInit(label, as.fe->numParams());
ch = as.in.getc();
if (ch == '(') {
String str = parse_long_string(as);
param.setPhpCode(StringData::GetStaticString(str));
TypedValue tv;
tvWriteUninit(&tv);
if (str.size() == 4) {
if (!strcasecmp("null", str.data())) {
tvWriteNull(&tv);
} else if (!strcasecmp("true", str.data())) {
tv = make_tv<KindOfBoolean>(true);
}
} else if (str.size() == 5 && !strcasecmp("false", str.data())) {
tv = make_tv<KindOfBoolean>(false);
}
if (tv.m_type != KindOfUninit) {
param.setDefaultValue(tv);
}
as.in.expectWs(')');
ch = as.in.getc();
}
} else {
if (inDVInits) {
as.error("all parameters after the first with a dv-initializer "
@@ -1417,6 +1448,8 @@ void parse_parameter_list(AsmState& as) {
}
}
as.fe->appendParam(StringData::GetStaticString(name), param);
if (ch == ')') break;
if (ch != ',') as.error("expected , between parameter names");
}
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
.function array_filter($arr = no_args, $func = no_func, $res = entry) {
.function array_filter($arr = no_args, $func = no_func("""null"""), $res = entry) {
.numiters 2;
# if we get here, a value was supplied for $res
+11
Ver Arquivo
@@ -0,0 +1,11 @@
<?php
function test() {
$x = new ReflectionFunction('array_filter');
$params = $x->getParameters();
$p1 = $params[1];
var_dump($p1->getDefaultValue());
var_dump($p1->getDefaultValueText());
}
test();
@@ -0,0 +1,2 @@
NULL
string(4) "null"