PageRenderTime 60ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/compiler/analysis/code_error.cpp

https://gitlab.com/alvinahmadov2/hhvm
C++ | 237 lines | 167 code | 43 blank | 27 comment | 18 complexity | 27b6cafca3cc1a6495bc8a02339cc130 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2015 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. +----------------------------------------------------------------------+
  15. */
  16. #include "hphp/compiler/analysis/code_error.h"
  17. #include <fstream>
  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"
  26. using namespace HPHP::JSON;
  27. namespace HPHP { namespace Compiler {
  28. ///////////////////////////////////////////////////////////////////////////////
  29. DECLARE_BOOST_TYPES(ErrorInfo);
  30. class ErrorInfo : public JSON::CodeError::ISerializable {
  31. public:
  32. ErrorType m_error;
  33. ConstructPtr m_construct1;
  34. ConstructPtr m_construct2;
  35. std::string m_data;
  36. /**
  37. * Implements JSON::CodeError::ISerializable.
  38. */
  39. virtual void serialize(JSON::CodeError::OutputStream &out) const;
  40. };
  41. ///////////////////////////////////////////////////////////////////////////////
  42. class CodeErrors : public JSON::CodeError::ISerializable {
  43. public:
  44. CodeErrors();
  45. void clear();
  46. /**
  47. * Implements JSON::CodeError::ISerializable.
  48. */
  49. virtual void serialize(JSON::CodeError::OutputStream &out) const;
  50. void record(ErrorInfoPtr errorInfo);
  51. bool exists(ErrorType type) const;
  52. bool exists() const;
  53. void saveToFile(AnalysisResultPtr ar,
  54. const char *filename, bool varWrapper) const;
  55. private:
  56. static std::vector<const char *> ErrorTexts;
  57. static std::vector<const char *> &getErrorTexts();
  58. typedef std::map<ConstructPtr, ErrorInfoPtr> ErrorInfoMap;
  59. std::vector<ErrorInfoMap> m_errors;
  60. Mutex m_mutex;
  61. };
  62. static CodeErrors s_code_errors;
  63. ///////////////////////////////////////////////////////////////////////////////
  64. // class CodeErrors
  65. std::vector<const char *> CodeErrors::ErrorTexts;
  66. std::vector<const char *> &CodeErrors::getErrorTexts() {
  67. if (ErrorTexts.empty()) {
  68. ErrorTexts.resize(ErrorCount);
  69. #define CODE_ERROR_ENTRY(x) ErrorTexts[x] = #x;
  70. #include "hphp/compiler/analysis/core_code_error.inc"
  71. #undef CODE_ERROR_ENTRY
  72. }
  73. return ErrorTexts;
  74. }
  75. CodeErrors::CodeErrors() {
  76. m_errors.resize(ErrorCount);
  77. }
  78. void CodeErrors::clear() {
  79. m_errors.clear();
  80. m_errors.resize(ErrorCount);
  81. }
  82. void CodeErrors::record(ErrorInfoPtr errorInfo) {
  83. assert(errorInfo->m_error >= 0 && errorInfo->m_error < ErrorCount);
  84. Lock lock(m_mutex);
  85. m_errors[errorInfo->m_error][errorInfo->m_construct1] = errorInfo;
  86. }
  87. bool CodeErrors::exists(ErrorType type) const {
  88. return !m_errors[type].empty();
  89. }
  90. bool CodeErrors::exists() const {
  91. for (unsigned int i = 0; i < m_errors.size(); i++) {
  92. const ErrorInfoMap &errorMap = m_errors[i];
  93. if (!errorMap.empty()) return true;
  94. }
  95. return false;
  96. }
  97. void ErrorInfo::serialize(JSON::CodeError::OutputStream &out) const {
  98. JSON::CodeError::MapStream ms(out);
  99. if (m_construct1) {
  100. ms.add("c1", m_construct1);
  101. }
  102. if (m_construct2) {
  103. ms.add("c2", m_construct2);
  104. }
  105. if (!m_data.empty()) {
  106. ms.add("d", m_data);
  107. }
  108. ms.done();
  109. }
  110. void CodeErrors::serialize(JSON::CodeError::OutputStream &out) const {
  111. auto errorTexts = getErrorTexts();
  112. unsigned int total = 0;
  113. for (unsigned int i = 0; i < m_errors.size(); i++) {
  114. total += m_errors[i].size();
  115. }
  116. JSON::CodeError::ListStream ls(out);
  117. ls << total;
  118. ls.next();
  119. JSON::CodeError::MapStream ms(out);
  120. for (unsigned int i = 0; i < m_errors.size(); i++) {
  121. const ErrorInfoMap &errorMap = m_errors[i];
  122. if (errorMap.empty()) continue;
  123. ms.add(errorTexts[i]);
  124. JSON::CodeError::ListStream ls2(out);
  125. for (ErrorInfoMap::const_iterator iter = errorMap.begin();
  126. iter != errorMap.end(); ++iter) {
  127. ls2 << iter->second;
  128. }
  129. ls2.done();
  130. }
  131. ms.done();
  132. ls.done();
  133. }
  134. void CodeErrors::saveToFile(AnalysisResultPtr ar,
  135. const char *filename,
  136. bool varWrapper) const {
  137. std::ofstream f(filename);
  138. if (f) {
  139. JSON::CodeError::OutputStream o(f, ar);
  140. if (varWrapper) f << "var CodeErrors = ";
  141. serialize(o);
  142. if (varWrapper) f << ";\n\n";
  143. f.close();
  144. }
  145. }
  146. ///////////////////////////////////////////////////////////////////////////////
  147. void ClearErrors() {
  148. s_code_errors.clear();
  149. }
  150. void Error(ErrorType error, ConstructPtr construct) {
  151. if (!Option::RecordErrors) return;
  152. ErrorInfoPtr errorInfo(new ErrorInfo());
  153. errorInfo->m_error = error;
  154. errorInfo->m_construct1 = construct;
  155. errorInfo->m_data = construct->getText();
  156. s_code_errors.record(errorInfo);
  157. }
  158. void Error(ErrorType error, ConstructPtr construct1, ConstructPtr construct2) {
  159. if (!Option::RecordErrors) return;
  160. ErrorInfoPtr errorInfo(new ErrorInfo());
  161. errorInfo->m_error = error;
  162. errorInfo->m_construct1 = construct1;
  163. errorInfo->m_construct2 = construct2;
  164. errorInfo->m_data = construct1->getText();
  165. s_code_errors.record(errorInfo);
  166. }
  167. void Error(ErrorType error, ConstructPtr construct, const std::string &data) {
  168. if (!Option::RecordErrors) return;
  169. ErrorInfoPtr errorInfo(new ErrorInfo());
  170. errorInfo->m_error = error;
  171. errorInfo->m_construct1 = construct;
  172. errorInfo->m_data = data;
  173. s_code_errors.record(errorInfo);
  174. }
  175. void SaveErrors(JSON::CodeError::OutputStream &out) {
  176. s_code_errors.serialize(out);
  177. }
  178. void SaveErrors(AnalysisResultPtr ar,
  179. const char *filename,
  180. bool varWrapper /* = false */) {
  181. s_code_errors.saveToFile(ar, filename, varWrapper);
  182. }
  183. void DumpErrors(AnalysisResultPtr ar) {
  184. JSON::CodeError::OutputStream o(std::cerr, ar);
  185. s_code_errors.serialize(o);
  186. }
  187. bool HasError(ErrorType type) {
  188. return s_code_errors.exists(type);
  189. }
  190. bool HasError() {
  191. return s_code_errors.exists();
  192. }
  193. ///////////////////////////////////////////////////////////////////////////////
  194. }}