Mark classes with the same name as a type alias as redeclaring @override-unit-failures

If you have an alias named "Foo", and a class named "Foo" in
the same program, we should not be treating instanceof (and probably
other things) as if the class name is unique.
Esse commit está contido em:
Jordan DeLong
2013-06-20 13:20:24 -07:00
commit de Sara Golemon
commit 1c710536b1
6 arquivos alterados com 52 adições e 12 exclusões
+22 -10
Ver Arquivo
@@ -423,6 +423,16 @@ void AnalysisResult::markRedeclaringClasses() {
}
}
auto markRedeclaring = [&] (const std::string& name) {
auto it = m_classDecs.find(name);
if (it != m_classDecs.end()) {
auto& classes = it->second;
for (unsigned int i = 0; i < classes.size(); ++i) {
classes[i]->setRedeclaring(ar, i);
}
}
};
/*
* In WholeProgram mode, during parse time we collected all
* class_alias calls so we can mark the targets of such calls
@@ -446,19 +456,19 @@ void AnalysisResult::markRedeclaringClasses() {
* as redeclaring for now.
*/
for (auto& kv : m_classAliases) {
auto markRedeclaring = [&] (const std::string& name) {
auto it = m_classDecs.find(name);
if (it != m_classDecs.end()) {
auto& classes = it->second;
for (unsigned int i = 0; i < classes.size(); ++i) {
classes[i]->setRedeclaring(ar, i);
}
}
};
markRedeclaring(Util::toLower(kv.first));
markRedeclaring(Util::toLower(kv.second));
}
/*
* Similar to class_alias, when a type alias is declared with the
* same name as a class in the program, we need to make sure the
* class is marked redeclaring. It is possible in some requests
* that things like 'instanceof Foo' will not mean the same thing.
*/
for (auto& name : m_typeAliasNames) {
markRedeclaring(Util::toLower(name));
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -643,6 +653,8 @@ void AnalysisResult::collectFunctionsAndClasses(FileScopePtr fs) {
m_classAliases.insert(fs->getClassAliases().begin(),
fs->getClassAliases().end());
m_typeAliasNames.insert(fs->getTypeAliasNames().begin(),
fs->getTypeAliasNames().end());
}
static bool by_filename(const FileScopePtr &f1, const FileScopePtr &f2) {
+3
Ver Arquivo
@@ -324,6 +324,9 @@ private:
// Only in WholeProgram mode. See markRedeclaringClasses.
std::multimap<std::string,std::string> m_classAliases;
// Names of type aliases.
std::set<std::string> m_typeAliasNames;
bool m_classForcedVariants[2];
StatementPtrVec m_stmts;
+13
Ver Arquivo
@@ -145,6 +145,14 @@ public:
return m_classAliasMap;
}
void addTypeAliasName(const std::string& name) {
m_typeAliasNames.insert(name);
}
std::set<std::string> const& getTypeAliasNames() const {
return m_typeAliasNames;
}
/**
* Called only by World
*/
@@ -217,6 +225,11 @@ private:
// This is only needed in WholeProgram mode.
std::multimap<std::string,std::string> m_classAliasMap;
// Set of names that are on the left hand side of type alias
// declarations. We need this to make sure we don't mark classes
// with the same name Unique.
std::set<std::string> m_typeAliasNames;
FunctionScopePtr createPseudoMain(AnalysisResultConstPtr ar);
void setFileLevel(StatementListPtr stmt);
};
+3 -1
Ver Arquivo
@@ -1634,7 +1634,9 @@ void Parser::onGoto(Token &out, Token &label, bool limited) {
}
void Parser::onTypedef(Token& out, const Token& name, const Token& type) {
out->stmt = NEW_STMT(TypedefStatement, name.text(), type.text());
auto td_stmt = NEW_STMT(TypedefStatement, name.text(), type.text());
td_stmt->onParse(m_ar, m_file);
out->stmt = td_stmt;
}
void Parser::onTypeAnnotation(Token& out, const Token& name,
@@ -15,6 +15,8 @@
*/
#include "hphp/compiler/statement/typedef_statement.h"
#include "hphp/compiler/analysis/file_scope.h"
namespace HPHP {
//////////////////////////////////////////////////////////////////////
@@ -57,6 +59,10 @@ void TypedefStatement::inferTypes(AnalysisResultPtr) {}
void TypedefStatement::outputPHP(CodeGenerator& cg, AnalysisResultPtr ar) {
}
void TypedefStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr scope) {
scope->addTypeAliasName(name);
}
//////////////////////////////////////////////////////////////////////
}
+5 -1
Ver Arquivo
@@ -25,7 +25,7 @@
namespace HPHP {
//////////////////////////////////////////////////////////////////////
struct TypedefStatement : Statement {
struct TypedefStatement : Statement, IParseHandler {
explicit TypedefStatement(STATEMENT_CONSTRUCTOR_PARAMETERS,
const std::string& name,
const std::string& value);
@@ -33,6 +33,10 @@ struct TypedefStatement : Statement {
DECLARE_STATEMENT_VIRTUAL_FUNCTIONS;
public: // IParseHandler
void onParse(AnalysisResultConstPtr, FileScopePtr);
public:
const std::string name;
const std::string value;
};