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/analysis/analysis_result.h"
19 #include <folly/Conv.h>
20 #include <folly/portability/SysStat.h>
30 #include "hphp/compiler/builtin_symbols.h"
31 #include "hphp/compiler/option.h"
32 #include "hphp/compiler/package.h"
33 #include "hphp/runtime/base/program-functions.h"
34 #include "hphp/runtime/vm/unit-emitter.h"
35 #include "hphp/runtime/vm/treadmill.h"
36 #include "hphp/util/hash.h"
37 #include "hphp/util/job-queue.h"
38 #include "hphp/util/logger.h"
39 #include "hphp/util/timer.h"
43 ///////////////////////////////////////////////////////////////////////////////
46 AnalysisResult::AnalysisResult()
47 : m_package(nullptr), m_parseOnDemand(false) {
48 if (RuntimeOption::EvalUseHHBBC
) {
49 m_program
= HHBBC::make_program();
53 AnalysisResult::~AnalysisResult() {
54 always_assert(!m_finish
);
57 void AnalysisResult::finish() {
59 // std::move leaves a std::function in a valid, but
60 // unspecified state. Don't try to replace this with a std::move
63 f(shared_from_this());
67 ///////////////////////////////////////////////////////////////////////////////
70 void AnalysisResult::addHhasFile(std::unique_ptr
<UnitEmitter
>&& ue
) {
71 Lock
lock(getMutex());
72 m_hhasFiles
.emplace_back(std::move(ue
));
75 std::vector
<std::unique_ptr
<UnitEmitter
>> AnalysisResult::getHhasFiles() {
76 return std::move(m_hhasFiles
);
79 bool AnalysisResult::inParseOnDemandDirs(const std::string
& filename
) const {
80 for (auto const& dir
: m_parseOnDemandDirs
) {
81 if (filename
.find(dir
) == 0) return true;
86 void AnalysisResult::parseOnDemand(const std::string
& name
) const {
88 auto const& root
= m_package
->getRoot();
90 if (rname
.compare(0, root
.length(), root
) == 0) {
91 rname
= rname
.substr(root
.length());
93 if ((m_parseOnDemand
|| inParseOnDemandDirs(rname
)) &&
94 Option::PackageExcludeFiles
.find(rname
) ==
95 Option::PackageExcludeFiles
.end() &&
96 !Option::IsFileExcluded(rname
, Option::PackageExcludePatterns
)) {
97 m_package
->addSourceFile(rname
);
103 void AnalysisResult::parseOnDemandBy(const CompactVector
<std::string
>& syms
,
104 const Map
& amap
) const {
106 for (auto const& name
: syms
) {
107 auto it
= amap
.find(name
);
108 if (it
!= amap
.end()) {
109 parseOnDemand(Option::AutoloadRoot
+ it
->second
);
115 void AnalysisResult::parseOnDemandBy(
116 SymbolRef kind
, const CompactVector
<std::string
>& syms
) const {
118 case SymbolRef::Include
:
119 for (auto const& name
: syms
) parseOnDemand(name
);
122 case SymbolRef::Class
:
123 return parseOnDemandBy(syms
, Option::AutoloadClassMap
);
125 case SymbolRef::Function
:
126 return parseOnDemandBy(syms
, Option::AutoloadFuncMap
);
128 case SymbolRef::Constant
:
129 return parseOnDemandBy(syms
, Option::AutoloadConstMap
);
134 ///////////////////////////////////////////////////////////////////////////////
135 // code generation functions
137 std::string
AnalysisResult::prepareFile(const char *root
,
138 const std::string
&fileName
,
140 bool stripPath
/* = true */) {
141 std::string fullPath
= root
;
142 if (!fullPath
.empty() &&
143 !FileUtil::isDirSeparator(fullPath
[fullPath
.size() - 1])) {
144 fullPath
+= FileUtil::getDirSeparator();
147 auto file
= fileName
;
149 size_t npos
= file
.rfind('/');
150 if (npos
!= std::string::npos
) {
151 file
= file
.substr(npos
+ 1);
155 if (chop
&& file
.size() > 4 && file
.substr(file
.length() - 4) == ".php") {
156 fullPath
+= file
.substr(0, file
.length() - 4);
160 for (size_t pos
= strlen(root
); pos
< fullPath
.size(); pos
++) {
161 if (FileUtil::isDirSeparator(fullPath
[pos
])) {
162 mkdir(fullPath
.substr(0, pos
).c_str(), 0777);