Remove deprecated slice() and kvzip() methods
[hiphop-php.git] / hphp / compiler / analysis / code_error.cpp
blob0576c59ebc2d6211d422833db3b171081aed6976
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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"
18 #include <map>
19 #include <vector>
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 {
34 public:
35 ErrorType m_error;
36 ConstructPtr m_construct1;
37 ConstructPtr m_construct2;
38 std::string m_data;
40 /**
41 * Implements JSON::CodeError::ISerializable.
43 virtual void serialize(JSON::CodeError::OutputStream &out) const;
46 ///////////////////////////////////////////////////////////////////////////////
48 class CodeErrors : public JSON::CodeError::ISerializable {
49 public:
50 CodeErrors();
51 void clear();
53 /**
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;
60 bool exists() const;
62 void saveToFile(AnalysisResultPtr ar,
63 const char *filename, bool varWrapper) const;
65 private:
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;
71 Mutex m_mutex;
74 static CodeErrors s_code_errors;
76 ///////////////////////////////////////////////////////////////////////////////
77 // class CodeErrors
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
87 return ErrorTexts;
90 CodeErrors::CodeErrors() {
91 m_errors.resize(ErrorCount);
94 void CodeErrors::clear() {
95 m_errors.clear();
96 m_errors.resize(ErrorCount);
99 void CodeErrors::record(ErrorInfoPtr errorInfo) {
100 assert(errorInfo->m_error >= 0 && errorInfo->m_error < ErrorCount);
101 Lock lock(m_mutex);
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;
114 return false;
117 void ErrorInfo::serialize(JSON::CodeError::OutputStream &out) const {
118 JSON::CodeError::MapStream ms(out);
119 if (m_construct1) {
120 ms.add("c1", m_construct1);
122 if (m_construct2) {
123 ms.add("c2", m_construct2);
125 if (!m_data.empty()) {
126 ms.add("d", m_data);
128 ms.done();
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);
140 ls << total;
141 ls.next();
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) {
153 ls2 << iter->second;
156 ls2.done();
159 ms.done();
160 ls.done();
163 void CodeErrors::saveToFile(AnalysisResultPtr ar,
164 const char *filename,
165 bool varWrapper) const {
166 std::ofstream f(filename);
167 if (f) {
168 JSON::CodeError::OutputStream o(f, ar);
169 if (varWrapper) f << "var CodeErrors = ";
170 serialize(o);
171 if (varWrapper) f << ";\n\n";
172 f.close();
176 ///////////////////////////////////////////////////////////////////////////////
178 void ClearErrors() {
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);
229 bool HasError() {
230 return s_code_errors.exists();
233 ///////////////////////////////////////////////////////////////////////////////