mirror of
https://github.com/php/php-src.git
synced 2026-04-01 21:22:13 +02:00
Merge branch 'use-function' of git://github.com/igorw/php-src into igorw-use-function
This commit is contained in:
26
Zend/tests/use_const/alias.phpt
Normal file
26
Zend/tests/use_const/alias.phpt
Normal file
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
aliasing imported constants to resolve naming conflicts
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo {
|
||||
const baz = 42;
|
||||
}
|
||||
|
||||
namespace bar {
|
||||
const baz = 43;
|
||||
}
|
||||
|
||||
namespace {
|
||||
use const foo\baz as foo_baz,
|
||||
bar\baz as bar_baz;
|
||||
var_dump(foo_baz);
|
||||
var_dump(bar_baz);
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(42)
|
||||
int(43)
|
||||
Done
|
||||
22
Zend/tests/use_const/basic.phpt
Normal file
22
Zend/tests/use_const/basic.phpt
Normal file
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
import namespaced constant
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo\bar {
|
||||
const baz = 42;
|
||||
const qux = 43;
|
||||
}
|
||||
|
||||
namespace {
|
||||
use const foo\bar\baz, foo\bar\qux;
|
||||
var_dump(baz);
|
||||
var_dump(qux);
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(42)
|
||||
int(43)
|
||||
Done
|
||||
12
Zend/tests/use_const/case_sensivity.phpt
Normal file
12
Zend/tests/use_const/case_sensivity.phpt
Normal file
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
importing const with same name but different case
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use const foo\bar;
|
||||
use const foo\BAR;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
21
Zend/tests/use_const/conflicting_use.phpt
Normal file
21
Zend/tests/use_const/conflicting_use.phpt
Normal file
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
use const statements with conflicting names
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo {
|
||||
const baz = 42;
|
||||
}
|
||||
|
||||
namespace bar {
|
||||
const baz = 42;
|
||||
}
|
||||
|
||||
namespace {
|
||||
use const foo\baz, bar\baz;
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use const bar\baz as baz because the name is already in use in %s on line %d
|
||||
18
Zend/tests/use_const/conflicting_use_alias.phpt
Normal file
18
Zend/tests/use_const/conflicting_use_alias.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
use and use const with the same alias
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
const foo = 'foo';
|
||||
}
|
||||
|
||||
namespace x {
|
||||
use foo as bar;
|
||||
use const foo as bar;
|
||||
var_dump(bar);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "foo"
|
||||
14
Zend/tests/use_const/define_imported.phpt
Normal file
14
Zend/tests/use_const/define_imported.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
defining const with same name as imported should fail
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use const foo\bar;
|
||||
|
||||
const bar = 42;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot declare const bar because the name is already in use in %s on line %d
|
||||
18
Zend/tests/use_const/define_imported_before.phpt
Normal file
18
Zend/tests/use_const/define_imported_before.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
using const with same name as defined should fail
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
const bar = 42;
|
||||
|
||||
use const foo\bar;
|
||||
}
|
||||
|
||||
namespace {
|
||||
echo "Done";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use const foo\bar as bar because the name is already in use in %s on line %d
|
||||
5
Zend/tests/use_const/includes/foo_bar.php
Normal file
5
Zend/tests/use_const/includes/foo_bar.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace foo;
|
||||
|
||||
const bar = 'local bar';
|
||||
5
Zend/tests/use_const/includes/foo_php_version.php
Normal file
5
Zend/tests/use_const/includes/foo_php_version.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace foo;
|
||||
|
||||
const PHP_VERSION = 42;
|
||||
3
Zend/tests/use_const/includes/global_bar.php
Normal file
3
Zend/tests/use_const/includes/global_bar.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
const bar = 'global bar';
|
||||
3
Zend/tests/use_const/includes/global_baz.php
Normal file
3
Zend/tests/use_const/includes/global_baz.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
const baz = NULL;
|
||||
14
Zend/tests/use_const/no_global_fallback.phpt
Normal file
14
Zend/tests/use_const/no_global_fallback.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
non-existent imported constants should not be looked up in the global table
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'includes/global_baz.php';
|
||||
|
||||
use const foo\bar\baz;
|
||||
var_dump(baz);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Use of undefined constant baz - assumed 'baz' in %s on line %d
|
||||
string(3) "baz"
|
||||
12
Zend/tests/use_const/self_parent.phpt
Normal file
12
Zend/tests/use_const/self_parent.phpt
Normal file
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Allow self and parent in use const statement
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use const self as foo;
|
||||
use const parent as bar;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
16
Zend/tests/use_const/shadow_core.phpt
Normal file
16
Zend/tests/use_const/shadow_core.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
shadowing a global core constant with a local version
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'includes/foo_php_version.php';
|
||||
|
||||
use const foo\PHP_VERSION;
|
||||
|
||||
var_dump(PHP_VERSION);
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(42)
|
||||
Done
|
||||
25
Zend/tests/use_const/shadow_global.phpt
Normal file
25
Zend/tests/use_const/shadow_global.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
shadowing a global constant with a local version
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
require 'includes/global_bar.php';
|
||||
require 'includes/foo_bar.php';
|
||||
}
|
||||
|
||||
namespace {
|
||||
var_dump(bar);
|
||||
}
|
||||
|
||||
namespace {
|
||||
use const foo\bar;
|
||||
var_dump(bar);
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(10) "global bar"
|
||||
string(9) "local bar"
|
||||
Done
|
||||
30
Zend/tests/use_function/alias.phpt
Normal file
30
Zend/tests/use_function/alias.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
aliasing imported functions to resolve naming conflicts
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo {
|
||||
function baz() {
|
||||
return 'foo.baz';
|
||||
}
|
||||
}
|
||||
|
||||
namespace bar {
|
||||
function baz() {
|
||||
return 'bar.baz';
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
use function foo\baz as foo_baz,
|
||||
bar\baz as bar_baz;
|
||||
var_dump(foo_baz());
|
||||
var_dump(bar_baz());
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(7) "foo.baz"
|
||||
string(7) "bar.baz"
|
||||
Done
|
||||
26
Zend/tests/use_function/basic.phpt
Normal file
26
Zend/tests/use_function/basic.phpt
Normal file
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
import namespaced function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo\bar {
|
||||
function baz() {
|
||||
return 'foo.bar.baz';
|
||||
}
|
||||
function qux() {
|
||||
return baz();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
use function foo\bar\baz, foo\bar\qux;
|
||||
var_dump(baz());
|
||||
var_dump(qux());
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(11) "foo.bar.baz"
|
||||
string(11) "foo.bar.baz"
|
||||
Done
|
||||
13
Zend/tests/use_function/case_insensivity.phpt
Normal file
13
Zend/tests/use_function/case_insensivity.phpt
Normal file
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
importing function with same name but different case should fail
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use function foo\bar;
|
||||
use function foo\BAR;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use function foo\BAR as BAR because the name is already in use in %s on line %d
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
function that is conditionally defined at runtime should not cause compiler error
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
if (0) {
|
||||
function foo() {
|
||||
}
|
||||
}
|
||||
|
||||
use function bar\foo;
|
||||
|
||||
echo "Done";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
25
Zend/tests/use_function/conflicting_use.phpt
Normal file
25
Zend/tests/use_function/conflicting_use.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
use function statements with conflicting names
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo {
|
||||
function baz() {
|
||||
return 'foo.baz';
|
||||
}
|
||||
}
|
||||
|
||||
namespace bar {
|
||||
function baz() {
|
||||
return 'bar.baz';
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
use function foo\baz, bar\baz;
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use function bar\baz as baz because the name is already in use in %s on line %d
|
||||
20
Zend/tests/use_function/conflicting_use_alias.phpt
Normal file
20
Zend/tests/use_function/conflicting_use_alias.phpt
Normal file
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
use and use function with the same alias
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
function foo() {
|
||||
return 'foo';
|
||||
}
|
||||
}
|
||||
|
||||
namespace x {
|
||||
use foo as bar;
|
||||
use function foo as bar;
|
||||
var_dump(bar());
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "foo"
|
||||
23
Zend/tests/use_function/conflicting_use_const_alias.phpt
Normal file
23
Zend/tests/use_function/conflicting_use_const_alias.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
use const and use function with the same alias
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
const foo = 'foo.const';
|
||||
function foo() {
|
||||
return 'foo.function';
|
||||
}
|
||||
}
|
||||
|
||||
namespace x {
|
||||
use const foo as bar;
|
||||
use function foo as bar;
|
||||
var_dump(bar);
|
||||
var_dump(bar());
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(9) "foo.const"
|
||||
string(12) "foo.function"
|
||||
14
Zend/tests/use_function/define_imported.phpt
Normal file
14
Zend/tests/use_function/define_imported.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
defining function with same name as imported should fail
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use function foo\bar;
|
||||
|
||||
function bar() {}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot declare function bar because the name is already in use in %s on line %d
|
||||
18
Zend/tests/use_function/define_imported_before.phpt
Normal file
18
Zend/tests/use_function/define_imported_before.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
using function with same name as defined should fail
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
function bar() {}
|
||||
|
||||
use function foo\bar;
|
||||
}
|
||||
|
||||
namespace {
|
||||
echo "Done";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use function foo\bar as bar because the name is already in use in %s on line %d
|
||||
23
Zend/tests/use_function/ignore_constants.phpt
Normal file
23
Zend/tests/use_function/ignore_constants.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
use function should ignore namespaced constants
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace foo {
|
||||
const bar = 42;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const bar = 43;
|
||||
}
|
||||
|
||||
namespace {
|
||||
use function foo\bar;
|
||||
var_dump(bar);
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(43)
|
||||
Done
|
||||
7
Zend/tests/use_function/includes/foo_bar.php
Normal file
7
Zend/tests/use_function/includes/foo_bar.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace foo;
|
||||
|
||||
function bar() {
|
||||
return 'local bar';
|
||||
}
|
||||
7
Zend/tests/use_function/includes/foo_strlen.php
Normal file
7
Zend/tests/use_function/includes/foo_strlen.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace foo;
|
||||
|
||||
function strlen($str) {
|
||||
return 4;
|
||||
}
|
||||
5
Zend/tests/use_function/includes/global_bar.php
Normal file
5
Zend/tests/use_function/includes/global_bar.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
function bar() {
|
||||
return 'global bar';
|
||||
}
|
||||
4
Zend/tests/use_function/includes/global_baz.php
Normal file
4
Zend/tests/use_function/includes/global_baz.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
function baz() {
|
||||
}
|
||||
13
Zend/tests/use_function/no_global_fallback.phpt
Normal file
13
Zend/tests/use_function/no_global_fallback.phpt
Normal file
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
non-existent imported functions should not be looked up in the global table
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'includes/global_baz.php';
|
||||
|
||||
use function foo\bar\baz;
|
||||
var_dump(baz());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Call to undefined function foo\bar\baz() in %s on line %d
|
||||
18
Zend/tests/use_function/no_global_fallback2.phpt
Normal file
18
Zend/tests/use_function/no_global_fallback2.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
non-existent imported functions should not be looked up in the global table
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
function test() {
|
||||
echo "NO!";
|
||||
}
|
||||
}
|
||||
namespace foo {
|
||||
use function bar\test;
|
||||
test();
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Call to undefined function bar\test() in %s on line %d
|
||||
12
Zend/tests/use_function/self_parent.phpt
Normal file
12
Zend/tests/use_function/self_parent.phpt
Normal file
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Allow self and parent in use function statement
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
use function self as foo;
|
||||
use function parent as bar;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
16
Zend/tests/use_function/shadow_core.phpt
Normal file
16
Zend/tests/use_function/shadow_core.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
shadowing a global core function with a local version
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'includes/foo_strlen.php';
|
||||
|
||||
use function foo\strlen;
|
||||
|
||||
var_dump(strlen('foo bar baz'));
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(4)
|
||||
Done
|
||||
25
Zend/tests/use_function/shadow_global.phpt
Normal file
25
Zend/tests/use_function/shadow_global.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
shadowing a global function with a local version
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
require 'includes/global_bar.php';
|
||||
require 'includes/foo_bar.php';
|
||||
}
|
||||
|
||||
namespace {
|
||||
var_dump(bar());
|
||||
}
|
||||
|
||||
namespace {
|
||||
use function foo\bar;
|
||||
var_dump(bar());
|
||||
echo "Done\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(10) "global bar"
|
||||
string(9) "local bar"
|
||||
Done
|
||||
@@ -197,6 +197,9 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
|
||||
CG(in_namespace) = 0;
|
||||
CG(has_bracketed_namespaces) = 0;
|
||||
CG(current_import) = NULL;
|
||||
CG(current_import_function) = NULL;
|
||||
CG(current_import_const) = NULL;
|
||||
zend_hash_init(&CG(const_filenames), 0, NULL, NULL, 0);
|
||||
init_compiler_declarables(TSRMLS_C);
|
||||
zend_stack_init(&CG(context_stack));
|
||||
|
||||
@@ -235,6 +238,7 @@ void shutdown_compiler(TSRMLS_D) /* {{{ */
|
||||
zend_stack_destroy(&CG(list_stack));
|
||||
zend_hash_destroy(&CG(filenames_table));
|
||||
zend_llist_destroy(&CG(open_files));
|
||||
zend_hash_destroy(&CG(const_filenames));
|
||||
zend_stack_destroy(&CG(context_stack));
|
||||
}
|
||||
/* }}} */
|
||||
@@ -417,12 +421,16 @@ int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS
|
||||
lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
|
||||
CALCULATE_LITERAL_HASH(lc_literal);
|
||||
|
||||
ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)) + 1;
|
||||
lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
|
||||
lc_name = zend_str_tolower_dup(ns_separator, lc_len);
|
||||
ZVAL_STRINGL(&c, lc_name, lc_len, 0);
|
||||
lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
|
||||
CALCULATE_LITERAL_HASH(lc_literal);
|
||||
ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv));
|
||||
|
||||
if (ns_separator != NULL) {
|
||||
ns_separator += 1;
|
||||
lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
|
||||
lc_name = zend_str_tolower_dup(ns_separator, lc_len);
|
||||
ZVAL_STRINGL(&c, lc_name, lc_len, 0);
|
||||
lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
|
||||
CALCULATE_LITERAL_HASH(lc_literal);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1684,6 +1692,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
|
||||
} else {
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
zval key;
|
||||
zval **ns_name;
|
||||
|
||||
if (CG(current_namespace)) {
|
||||
/* Prefix function name with current namespace name */
|
||||
@@ -1699,18 +1708,32 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
|
||||
lcname = zend_str_tolower_dup(name, name_len);
|
||||
}
|
||||
|
||||
/* Function name must not conflict with import names */
|
||||
if (CG(current_import_function) &&
|
||||
zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
|
||||
|
||||
char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
|
||||
|
||||
if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) ||
|
||||
memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant));
|
||||
}
|
||||
efree(tmp);
|
||||
}
|
||||
|
||||
opline->opcode = ZEND_DECLARE_FUNCTION;
|
||||
opline->op1_type = IS_CONST;
|
||||
build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC);
|
||||
opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
|
||||
Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
|
||||
opline->op2_type = IS_CONST;
|
||||
LITERAL_STRINGL(opline->op2, lcname, name_len, 0);
|
||||
LITERAL_STRINGL(opline->op2, lcname, name_len, 1);
|
||||
CALCULATE_LITERAL_HASH(opline->op2.constant);
|
||||
opline->extended_value = ZEND_DECLARE_FUNCTION;
|
||||
zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
|
||||
zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
|
||||
zend_init_compiler_context(TSRMLS_C);
|
||||
str_efree(lcname);
|
||||
}
|
||||
|
||||
if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
|
||||
@@ -1933,7 +1956,7 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
|
||||
char *lcname;
|
||||
char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant));
|
||||
|
||||
zend_resolve_non_class_name(function_name, check_namespace TSRMLS_CC);
|
||||
zend_resolve_function_name(function_name, &check_namespace TSRMLS_CC);
|
||||
|
||||
if (check_namespace && CG(current_namespace) && !is_compound) {
|
||||
/* We assume we call function from the current namespace
|
||||
@@ -2070,12 +2093,12 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */
|
||||
void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
znode tmp;
|
||||
int len;
|
||||
zval **ns;
|
||||
char *lcname, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant));
|
||||
char *lookup_name, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant));
|
||||
|
||||
if (Z_STRVAL(element_name->u.constant)[0] == '\\') {
|
||||
/* name starts with \ so it is known and unambiguos, nothing to do here but shorten it */
|
||||
@@ -2084,15 +2107,35 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace
|
||||
return;
|
||||
}
|
||||
|
||||
if(!check_namespace) {
|
||||
if(!*check_namespace) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_import_sub) {
|
||||
len = Z_STRLEN(element_name->u.constant)+1;
|
||||
if (case_sensitive) {
|
||||
lookup_name = estrndup(Z_STRVAL(element_name->u.constant), len);
|
||||
} else {
|
||||
lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
|
||||
}
|
||||
/* Check if function/const matches imported name */
|
||||
if (zend_hash_find(current_import_sub, lookup_name, len, (void**)&ns) == SUCCESS) {
|
||||
zval_dtor(&element_name->u.constant);
|
||||
element_name->u.constant = **ns;
|
||||
zval_copy_ctor(&element_name->u.constant);
|
||||
efree(lookup_name);
|
||||
*check_namespace = 0;
|
||||
return;
|
||||
}
|
||||
efree(lookup_name);
|
||||
}
|
||||
|
||||
if (compound && CG(current_import)) {
|
||||
len = compound - Z_STRVAL(element_name->u.constant);
|
||||
lcname = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
|
||||
/* namespace is always lowercase */
|
||||
lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
|
||||
/* Check if first part of compound name is an import name */
|
||||
if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) {
|
||||
if (zend_hash_find(CG(current_import), lookup_name, len+1, (void**)&ns) == SUCCESS) {
|
||||
/* Substitute import name */
|
||||
tmp.op_type = IS_CONST;
|
||||
tmp.u.constant = **ns;
|
||||
@@ -2102,10 +2145,11 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace
|
||||
memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+len, Z_STRLEN(element_name->u.constant)+1);
|
||||
zend_do_build_namespace_name(&tmp, &tmp, element_name TSRMLS_CC);
|
||||
*element_name = tmp;
|
||||
efree(lcname);
|
||||
efree(lookup_name);
|
||||
*check_namespace = 0;
|
||||
return;
|
||||
}
|
||||
efree(lcname);
|
||||
efree(lookup_name);
|
||||
}
|
||||
|
||||
if (CG(current_namespace)) {
|
||||
@@ -2121,6 +2165,18 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_resolve_non_class_name(element_name, check_namespace, 0, CG(current_import_function) TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_resolve_non_class_name(element_name, check_namespace, 1, CG(current_import_const) TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *lcname;
|
||||
@@ -5618,7 +5674,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
|
||||
break;
|
||||
}
|
||||
|
||||
zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
|
||||
zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC);
|
||||
|
||||
if(!compound) {
|
||||
fetch_type |= IS_CONSTANT_UNQUALIFIED;
|
||||
@@ -5630,7 +5686,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
|
||||
case ZEND_RT:
|
||||
compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
|
||||
|
||||
zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
|
||||
zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC);
|
||||
|
||||
if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) {
|
||||
break;
|
||||
@@ -6981,6 +7037,18 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC
|
||||
CG(current_import) = NULL;
|
||||
}
|
||||
|
||||
if (CG(current_import_function)) {
|
||||
zend_hash_destroy(CG(current_import_function));
|
||||
efree(CG(current_import_function));
|
||||
CG(current_import_function) = NULL;
|
||||
}
|
||||
|
||||
if (CG(current_import_const)) {
|
||||
zend_hash_destroy(CG(current_import_const));
|
||||
efree(CG(current_import_const));
|
||||
CG(current_import_const) = NULL;
|
||||
}
|
||||
|
||||
if (CG(doc_comment)) {
|
||||
efree(CG(doc_comment));
|
||||
CG(doc_comment) = NULL;
|
||||
@@ -7002,7 +7070,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{
|
||||
}
|
||||
|
||||
ALLOC_ZVAL(ns);
|
||||
*ns = ns_name->u.constant;
|
||||
ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0);
|
||||
if (new_name) {
|
||||
name = &new_name->u.constant;
|
||||
} else {
|
||||
@@ -7015,8 +7083,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{
|
||||
if (p) {
|
||||
ZVAL_STRING(name, p+1, 1);
|
||||
} else {
|
||||
*name = *ns;
|
||||
zval_copy_ctor(name);
|
||||
ZVAL_ZVAL(name, ns, 1, 0);
|
||||
warn = !is_global && !CG(current_namespace);
|
||||
}
|
||||
}
|
||||
@@ -7073,9 +7140,117 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *lookup_name;
|
||||
zval *name, *ns, tmp;
|
||||
zend_bool warn = 0;
|
||||
|
||||
ALLOC_ZVAL(ns);
|
||||
ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0);
|
||||
if (new_name) {
|
||||
name = &new_name->u.constant;
|
||||
} else {
|
||||
const char *p;
|
||||
|
||||
/* The form "use A\B" is eqivalent to "use A\B as B".
|
||||
So we extract the last part of compound name to use as a new_name */
|
||||
name = &tmp;
|
||||
p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns));
|
||||
if (p) {
|
||||
ZVAL_STRING(name, p+1, 1);
|
||||
} else {
|
||||
ZVAL_ZVAL(name, ns, 1, 0);
|
||||
warn = !is_global && !CG(current_namespace);
|
||||
}
|
||||
}
|
||||
|
||||
if (case_sensitive) {
|
||||
lookup_name = estrndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
|
||||
} else {
|
||||
lookup_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
|
||||
}
|
||||
|
||||
if (CG(current_namespace)) {
|
||||
/* Prefix import name with current namespace name to avoid conflicts with functions/consts */
|
||||
char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1);
|
||||
|
||||
zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
|
||||
c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\';
|
||||
memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lookup_name, Z_STRLEN_P(name)+1);
|
||||
if (zend_hash_exists(lookup_table, c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) {
|
||||
char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
|
||||
|
||||
if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) ||
|
||||
memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name));
|
||||
}
|
||||
efree(tmp2);
|
||||
}
|
||||
efree(c_ns_name);
|
||||
} else if (is_function) {
|
||||
zend_function *function;
|
||||
|
||||
if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &function) == SUCCESS && function->type == ZEND_USER_FUNCTION && strcmp(function->op_array.filename, CG(compiled_filename)) == 0) {
|
||||
char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
|
||||
|
||||
if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
|
||||
memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use function %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
|
||||
}
|
||||
efree(c_tmp);
|
||||
}
|
||||
} else {
|
||||
const char *filename;
|
||||
|
||||
if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &filename) == SUCCESS && strcmp(filename, CG(compiled_filename)) == 0) {
|
||||
char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
|
||||
|
||||
if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
|
||||
memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use const %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
|
||||
}
|
||||
efree(c_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_hash_add(current_import_sub, lookup_name, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name));
|
||||
}
|
||||
if (warn) {
|
||||
zend_error(E_WARNING, "The use %s statement with non-compound name '%s' has no effect", is_function ? "function" : "const", Z_STRVAL_P(name));
|
||||
}
|
||||
efree(lookup_name);
|
||||
zval_dtor(name);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_use_function(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (!CG(current_import_function)) {
|
||||
CG(current_import_function) = emalloc(sizeof(HashTable));
|
||||
zend_hash_init(CG(current_import_function), 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
|
||||
zend_do_use_non_class(ns_name, new_name, is_global, 1, 0, CG(current_import_function), CG(function_table) TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_use_const(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (!CG(current_import_const)) {
|
||||
CG(current_import_const) = emalloc(sizeof(HashTable));
|
||||
zend_hash_init(CG(current_import_const), 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
|
||||
zend_do_use_non_class(ns_name, new_name, is_global, 0, 1, CG(current_import_const), &CG(const_filenames) TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_op *opline;
|
||||
zval **ns_name;
|
||||
|
||||
if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants");
|
||||
@@ -7096,11 +7271,26 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
|
||||
*name = tmp;
|
||||
}
|
||||
|
||||
/* Constant name must not conflict with import names */
|
||||
if (CG(current_import_const) &&
|
||||
zend_hash_find(CG(current_import_const), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
|
||||
|
||||
char *tmp = estrndup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
|
||||
|
||||
if (Z_STRLEN_PP(ns_name) != Z_STRLEN(name->u.constant) ||
|
||||
memcmp(tmp, Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant))) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot declare const %s because the name is already in use", Z_STRVAL(name->u.constant));
|
||||
}
|
||||
efree(tmp);
|
||||
}
|
||||
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
opline->opcode = ZEND_DECLARE_CONST;
|
||||
SET_UNUSED(opline->result);
|
||||
SET_NODE(opline->op1, name);
|
||||
SET_NODE(opline->op2, value);
|
||||
|
||||
zend_hash_add(&CG(const_filenames), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, CG(compiled_filename), strlen(CG(compiled_filename))+1, NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -7125,6 +7315,16 @@ void zend_do_end_namespace(TSRMLS_D) /* {{{ */
|
||||
efree(CG(current_import));
|
||||
CG(current_import) = NULL;
|
||||
}
|
||||
if (CG(current_import_function)) {
|
||||
zend_hash_destroy(CG(current_import_function));
|
||||
efree(CG(current_import_function));
|
||||
CG(current_import_function) = NULL;
|
||||
}
|
||||
if (CG(current_import_const)) {
|
||||
zend_hash_destroy(CG(current_import_const));
|
||||
efree(CG(current_import_const));
|
||||
CG(current_import_const) = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct _zend_literal {
|
||||
#define Z_HASH_P(zv) \
|
||||
(((zend_literal*)(zv))->hash_value)
|
||||
|
||||
typedef union _znode_op {
|
||||
typedef union _znode_op {
|
||||
zend_uint constant;
|
||||
zend_uint var;
|
||||
zend_uint num;
|
||||
@@ -87,7 +87,7 @@ typedef union _znode_op {
|
||||
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
|
||||
} znode_op;
|
||||
|
||||
typedef struct _znode { /* used only during compilation */
|
||||
typedef struct _znode { /* used only during compilation */
|
||||
int op_type;
|
||||
union {
|
||||
znode_op op;
|
||||
@@ -244,7 +244,7 @@ typedef struct _zend_arg_info {
|
||||
} zend_arg_info;
|
||||
|
||||
/* the following structure repeats the layout of zend_arg_info,
|
||||
* but its fields have different meaning. It's used as the first element of
|
||||
* but its fields have different meaning. It's used as the first element of
|
||||
* arg_info array to define properties of internal functions.
|
||||
*/
|
||||
typedef struct _zend_internal_function_info {
|
||||
@@ -267,7 +267,7 @@ typedef struct _zend_compiled_variable {
|
||||
struct _zend_op_array {
|
||||
/* Common elements */
|
||||
zend_uchar type;
|
||||
const char *function_name;
|
||||
const char *function_name;
|
||||
zend_class_entry *scope;
|
||||
zend_uint fn_flags;
|
||||
union _zend_function *prototype;
|
||||
@@ -443,7 +443,9 @@ ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
|
||||
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
|
||||
ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
|
||||
|
||||
void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC);
|
||||
void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC);
|
||||
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
||||
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
||||
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
|
||||
ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len);
|
||||
|
||||
@@ -642,6 +644,9 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_brackets TSRMLS_D
|
||||
void zend_do_end_namespace(TSRMLS_D);
|
||||
void zend_verify_namespace(TSRMLS_D);
|
||||
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
||||
void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC);
|
||||
void zend_do_use_function(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
||||
void zend_do_use_const(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
||||
void zend_do_end_compilation(TSRMLS_D);
|
||||
void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC);
|
||||
|
||||
@@ -681,7 +686,7 @@ void zend_class_add_ref(zend_class_entry **ce);
|
||||
|
||||
ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal);
|
||||
#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
|
||||
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
|
||||
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
|
||||
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
|
||||
|
||||
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
|
||||
|
||||
@@ -131,9 +131,13 @@ struct _zend_compiler_globals {
|
||||
|
||||
zval *current_namespace;
|
||||
HashTable *current_import;
|
||||
HashTable *current_import_function;
|
||||
HashTable *current_import_const;
|
||||
zend_bool in_namespace;
|
||||
zend_bool has_bracketed_namespaces;
|
||||
|
||||
HashTable const_filenames;
|
||||
|
||||
zend_compiler_context context;
|
||||
zend_stack context_stack;
|
||||
|
||||
|
||||
@@ -241,6 +241,8 @@ top_statement:
|
||||
| T_NAMESPACE '{' { zend_do_begin_namespace(NULL, 1 TSRMLS_CC); }
|
||||
top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); }
|
||||
| T_USE use_declarations ';' { zend_verify_namespace(TSRMLS_C); }
|
||||
| T_USE T_FUNCTION use_function_declarations ';' { zend_verify_namespace(TSRMLS_C); }
|
||||
| T_USE T_CONST use_const_declarations ';' { zend_verify_namespace(TSRMLS_C); }
|
||||
| constant_declaration ';' { zend_verify_namespace(TSRMLS_C); }
|
||||
;
|
||||
|
||||
@@ -256,6 +258,30 @@ use_declaration:
|
||||
| T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use(&$2, &$4, 1 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
use_function_declarations:
|
||||
use_function_declarations ',' use_function_declaration
|
||||
| use_function_declaration
|
||||
;
|
||||
|
||||
use_function_declaration:
|
||||
namespace_name { zend_do_use_function(&$1, NULL, 0 TSRMLS_CC); }
|
||||
| namespace_name T_AS T_STRING { zend_do_use_function(&$1, &$3, 0 TSRMLS_CC); }
|
||||
| T_NS_SEPARATOR namespace_name { zend_do_use_function(&$2, NULL, 1 TSRMLS_CC); }
|
||||
| T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_function(&$2, &$4, 1 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
use_const_declarations:
|
||||
use_const_declarations ',' use_const_declaration
|
||||
| use_const_declaration
|
||||
;
|
||||
|
||||
use_const_declaration:
|
||||
namespace_name { zend_do_use_const(&$1, NULL, 0 TSRMLS_CC); }
|
||||
| namespace_name T_AS T_STRING { zend_do_use_const(&$1, &$3, 0 TSRMLS_CC); }
|
||||
| T_NS_SEPARATOR namespace_name { zend_do_use_const(&$2, NULL, 1 TSRMLS_CC); }
|
||||
| T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_const(&$2, &$4, 1 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
constant_declaration:
|
||||
constant_declaration ',' T_STRING '=' static_scalar { zend_do_declare_constant(&$3, &$5 TSRMLS_CC); }
|
||||
| T_CONST T_STRING '=' static_scalar { zend_do_declare_constant(&$2, &$4 TSRMLS_CC); }
|
||||
|
||||
Reference in New Issue
Block a user