Don't allow use Foo where Foo is already a class
Classes need to take up space in the alias map (according to zend). Suprisingly, functions and constants don't. When importing a duplicate, zend doesn't do anything and just continues, and we currently overwrite the symbol. Should I match zend on this, or is the fact that we both continue working good enough?
Esse commit está contido em:
@@ -965,6 +965,7 @@ void Parser::onClass(Token &out, int type, Token &name, Token &base,
|
||||
}
|
||||
m_clsName.clear();
|
||||
m_inTrait = false;
|
||||
registerAlias(name.text());
|
||||
}
|
||||
|
||||
void Parser::onInterface(Token &out, Token &name, Token &base, Token &stmt,
|
||||
@@ -1687,11 +1688,6 @@ void Parser::onNamespaceEnd() {
|
||||
}
|
||||
|
||||
void Parser::onUse(const std::string &ns, const std::string &as) {
|
||||
if (m_aliases.find(as) != m_aliases.end()) {
|
||||
error("Cannot use %s as %s because the name is already in use: %s",
|
||||
ns.c_str(), as.c_str(), getMessage().c_str());
|
||||
return;
|
||||
}
|
||||
string key = as;
|
||||
if (key.empty()) {
|
||||
size_t pos = ns.rfind(NAMESPACE_SEP);
|
||||
@@ -1701,6 +1697,11 @@ void Parser::onUse(const std::string &ns, const std::string &as) {
|
||||
key = ns.substr(pos + 1);
|
||||
}
|
||||
}
|
||||
if (m_aliases.find(key) != m_aliases.end() && m_aliases[key] != ns) {
|
||||
error("Cannot use %s as %s because the name is already in use: %s",
|
||||
ns.c_str(), key.c_str(), getMessage().c_str());
|
||||
return;
|
||||
}
|
||||
m_aliases[key] = ns;
|
||||
}
|
||||
|
||||
@@ -1787,5 +1788,13 @@ bool Parser::hasType(Token &type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Parser::registerAlias(std::string name) {
|
||||
size_t pos = name.rfind(NAMESPACE_SEP);
|
||||
if (pos != string::npos) {
|
||||
string key = name.substr(pos + 1);
|
||||
m_aliases[key] = name;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}}
|
||||
|
||||
@@ -344,6 +344,7 @@ private:
|
||||
bool m_nsFileScope;
|
||||
std::string m_namespace; // current namespace
|
||||
hphp_string_imap<std::string> m_aliases;
|
||||
void registerAlias(std::string name);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace A;
|
||||
const CO = "a";
|
||||
function f() { return "a"; }
|
||||
|
||||
namespace B;
|
||||
const CO = "b";
|
||||
function f() { return "b"; }
|
||||
|
||||
use A\f;
|
||||
use A\CO;
|
||||
var_dump(f());
|
||||
var_dump(CO);
|
||||
@@ -0,0 +1,2 @@
|
||||
string(1) "b"
|
||||
string(1) "b"
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace A;
|
||||
class Cl { public function __construct() { return "a"; } }
|
||||
|
||||
namespace B;
|
||||
class Cl { public function __construct() { return "b"; } }
|
||||
use A\Cl;
|
||||
@@ -0,0 +1 @@
|
||||
HipHop Fatal error: Cannot use A\\Cl as Cl because the name is already in use: (Line: 8, Char: 9) in %s on line 8
|
||||
Referência em uma Nova Issue
Bloquear um usuário