2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/compiler/expression/static_class_name.h"
18 #include "hphp/compiler/expression/scalar_expression.h"
19 #include "hphp/compiler/expression/simple_variable.h"
20 #include "hphp/compiler/statement/statement_list.h"
21 #include "hphp/compiler/analysis/class_scope.h"
22 #include "hphp/compiler/analysis/file_scope.h"
23 #include "hphp/compiler/analysis/variable_table.h"
24 #include "hphp/util/text-util.h"
27 ///////////////////////////////////////////////////////////////////////////////
29 StaticClassName::StaticClassName(ExpressionPtr classExp
)
31 m_self(false), m_parent(false), m_static(false),
32 m_redeclared(false), m_present(false), m_unknown(true) {
34 auto const isame
= [](const std::string
& a
, const std::string
& b
) {
35 return (a
.size() == b
.size()) &&
36 !strncasecmp(a
.c_str(), b
.c_str(), a
.size());
38 if (isame(m_origClassName
, "parent")) {
40 } else if (isame(m_origClassName
, "self")) {
42 } else if (isame(m_origClassName
, "static")) {
50 void StaticClassName::onParse(AnalysisResultConstPtr ar
, FileScopePtr scope
) {
51 if (!m_self
&& !m_parent
&& !m_static
&& hasStaticClass()) {
52 ar
->parseOnDemandByClass(m_origClassName
);
56 bool StaticClassName::isNamed(folly::StringPiece clsName
) const {
57 return bstrcasecmp(m_origClassName
, clsName
) == 0;
60 void StaticClassName::updateClassName() {
61 if (m_class
&& m_class
->is(Expression::KindOfScalarExpression
) &&
63 auto s
= dynamic_pointer_cast
<ScalarExpression
>(m_class
);
64 auto const& className
= s
->getString();
65 m_origClassName
= className
;
72 ClassScopePtr
StaticClassName::resolveClass() {
75 if (m_class
) return ClassScopePtr();
76 auto scope
= dynamic_cast<Construct
*>(this)->getScope();
78 if (ClassScopePtr self
= scope
->getContainingClass()) {
79 m_origClassName
= self
->getOriginalName();
84 } else if (m_parent
) {
85 if (ClassScopePtr self
= scope
->getContainingClass()) {
86 if (!self
->getOriginalParent().empty()) {
87 m_origClassName
= self
->getOriginalParent();
94 ClassScopePtr cls
= scope
->getContainingProgram()->findClass(m_origClassName
);
97 if (cls
->isVolatile()) {
98 ClassScopeRawPtr c
= scope
->getContainingClass();
99 if (c
&& c
->isNamed(m_origClassName
)) {
102 m_present
= c
.get() != nullptr;
103 if (cls
->isRedeclaring()) {
105 if (!m_present
) m_redeclared
= true;
114 ///////////////////////////////////////////////////////////////////////////////
116 void StaticClassName::outputPHP(CodeGenerator
&cg
, AnalysisResultPtr ar
) {
118 m_class
->outputPHP(cg
, ar
);
120 cg_printf("%s", m_origClassName
.c_str());
124 ///////////////////////////////////////////////////////////////////////////////