2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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/code_error.h"
20 #include "hphp/compiler/analysis/file_scope.h"
21 #include "hphp/compiler/parser/parser.h"
22 #include "hphp/compiler/construct.h"
23 #include "hphp/compiler/option.h"
24 #include "hphp/util/exception.h"
25 #include "hphp/util/lock.h"
27 using namespace HPHP::JSON
;
29 namespace HPHP
{ namespace Compiler
{
30 ///////////////////////////////////////////////////////////////////////////////
32 DECLARE_BOOST_TYPES(ErrorInfo
);
33 class ErrorInfo
: public JSON::CodeError::ISerializable
{
36 ConstructPtr m_construct1
;
37 ConstructPtr m_construct2
;
41 * Implements JSON::CodeError::ISerializable.
43 virtual void serialize(JSON::CodeError::OutputStream
&out
) const;
46 ///////////////////////////////////////////////////////////////////////////////
48 class CodeErrors
: public JSON::CodeError::ISerializable
{
54 * Implements JSON::CodeError::ISerializable.
56 virtual void serialize(JSON::CodeError::OutputStream
&out
) const;
58 void record(ErrorInfoPtr errorInfo
);
59 bool exists(ErrorType type
) const;
62 void saveToFile(AnalysisResultPtr ar
,
63 const char *filename
, bool varWrapper
) const;
66 static std::vector
<const char *> ErrorTexts
;
67 static std::vector
<const char *> &getErrorTexts();
69 typedef std::map
<ConstructPtr
, ErrorInfoPtr
> ErrorInfoMap
;
70 std::vector
<ErrorInfoMap
> m_errors
;
74 static CodeErrors s_code_errors
;
76 ///////////////////////////////////////////////////////////////////////////////
79 std::vector
<const char *> CodeErrors::ErrorTexts
;
80 std::vector
<const char *> &CodeErrors::getErrorTexts() {
81 if (ErrorTexts
.empty()) {
82 ErrorTexts
.resize(ErrorCount
);
83 #define CODE_ERROR_ENTRY(x) ErrorTexts[x] = #x;
84 #include "hphp/compiler/analysis/core_code_error.inc"
85 #undef CODE_ERROR_ENTRY
90 CodeErrors::CodeErrors() {
91 m_errors
.resize(ErrorCount
);
94 void CodeErrors::clear() {
96 m_errors
.resize(ErrorCount
);
99 void CodeErrors::record(ErrorInfoPtr errorInfo
) {
100 assert(errorInfo
->m_error
>= 0 && errorInfo
->m_error
< ErrorCount
);
102 m_errors
[errorInfo
->m_error
][errorInfo
->m_construct1
] = errorInfo
;
105 bool CodeErrors::exists(ErrorType type
) const {
106 return !m_errors
[type
].empty();
109 bool CodeErrors::exists() const {
110 for (unsigned int i
= 0; i
< m_errors
.size(); i
++) {
111 const ErrorInfoMap
&errorMap
= m_errors
[i
];
112 if (!errorMap
.empty()) return true;
117 void ErrorInfo::serialize(JSON::CodeError::OutputStream
&out
) const {
118 JSON::CodeError::MapStream
ms(out
);
120 ms
.add("c1", m_construct1
);
123 ms
.add("c2", m_construct2
);
125 if (!m_data
.empty()) {
131 void CodeErrors::serialize(JSON::CodeError::OutputStream
&out
) const {
132 vector
<const char *> errorTexts
= getErrorTexts();
134 unsigned int total
= 0;
135 for (unsigned int i
= 0; i
< m_errors
.size(); i
++) {
136 total
+= m_errors
[i
].size();
139 JSON::CodeError::ListStream
ls(out
);
143 JSON::CodeError::MapStream
ms(out
);
144 for (unsigned int i
= 0; i
< m_errors
.size(); i
++) {
145 const ErrorInfoMap
&errorMap
= m_errors
[i
];
146 if (errorMap
.empty()) continue;
148 ms
.add(errorTexts
[i
]);
149 JSON::CodeError::ListStream
ls2(out
);
151 for (ErrorInfoMap::const_iterator iter
= errorMap
.begin();
152 iter
!= errorMap
.end(); ++iter
) {
163 void CodeErrors::saveToFile(AnalysisResultPtr ar
,
164 const char *filename
,
165 bool varWrapper
) const {
166 std::ofstream
f(filename
);
168 JSON::CodeError::OutputStream
o(f
, ar
);
169 if (varWrapper
) f
<< "var CodeErrors = ";
171 if (varWrapper
) f
<< ";\n\n";
176 ///////////////////////////////////////////////////////////////////////////////
179 s_code_errors
.clear();
182 void Error(ErrorType error
, ConstructPtr construct
) {
183 if (!Option::RecordErrors
) return;
184 ErrorInfoPtr
errorInfo(new ErrorInfo());
185 errorInfo
->m_error
= error
;
186 errorInfo
->m_construct1
= construct
;
187 errorInfo
->m_data
= construct
->getText();
188 s_code_errors
.record(errorInfo
);
191 void Error(ErrorType error
, ConstructPtr construct1
, ConstructPtr construct2
) {
192 if (!Option::RecordErrors
) return;
193 ErrorInfoPtr
errorInfo(new ErrorInfo());
194 errorInfo
->m_error
= error
;
195 errorInfo
->m_construct1
= construct1
;
196 errorInfo
->m_construct2
= construct2
;
197 errorInfo
->m_data
= construct1
->getText();
198 s_code_errors
.record(errorInfo
);
201 void Error(ErrorType error
, ConstructPtr construct
, const std::string
&data
) {
202 if (!Option::RecordErrors
) return;
203 ErrorInfoPtr
errorInfo(new ErrorInfo());
204 errorInfo
->m_error
= error
;
205 errorInfo
->m_construct1
= construct
;
206 errorInfo
->m_data
= data
;
207 s_code_errors
.record(errorInfo
);
210 void SaveErrors(JSON::CodeError::OutputStream
&out
) {
211 s_code_errors
.serialize(out
);
214 void SaveErrors(AnalysisResultPtr ar
,
215 const char *filename
,
216 bool varWrapper
/* = false */) {
217 s_code_errors
.saveToFile(ar
, filename
, varWrapper
);
220 void DumpErrors(AnalysisResultPtr ar
) {
221 JSON::CodeError::OutputStream
o(std::cerr
, ar
);
222 s_code_errors
.serialize(o
);
225 bool HasError(ErrorType type
) {
226 return s_code_errors
.exists(type
);
230 return s_code_errors
.exists();
233 ///////////////////////////////////////////////////////////////////////////////