11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_
61cb0ef41Sopenharmony_ci#define V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <forward_list>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/base/export-template.h"
111cb0ef41Sopenharmony_ci#include "src/base/macros.h"
121cb0ef41Sopenharmony_ci#include "src/common/globals.h"
131cb0ef41Sopenharmony_ci#include "src/common/message-template.h"
141cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace v8 {
171cb0ef41Sopenharmony_cinamespace internal {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass AstRawString;
201cb0ef41Sopenharmony_ciclass AstValueFactory;
211cb0ef41Sopenharmony_ciclass Isolate;
221cb0ef41Sopenharmony_ciclass Script;
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// Helper class for handling pending compilation errors consistently in various
251cb0ef41Sopenharmony_ci// compilation phases.
261cb0ef41Sopenharmony_ciclass PendingCompilationErrorHandler {
271cb0ef41Sopenharmony_ci public:
281cb0ef41Sopenharmony_ci  PendingCompilationErrorHandler() = default;
291cb0ef41Sopenharmony_ci  PendingCompilationErrorHandler(const PendingCompilationErrorHandler&) =
301cb0ef41Sopenharmony_ci      delete;
311cb0ef41Sopenharmony_ci  PendingCompilationErrorHandler& operator=(
321cb0ef41Sopenharmony_ci      const PendingCompilationErrorHandler&) = delete;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  void ReportMessageAt(int start_position, int end_position,
351cb0ef41Sopenharmony_ci                       MessageTemplate message, const char* arg = nullptr);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  void ReportMessageAt(int start_position, int end_position,
381cb0ef41Sopenharmony_ci                       MessageTemplate message, const AstRawString* arg);
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  void ReportMessageAt(int start_position, int end_position,
411cb0ef41Sopenharmony_ci                       MessageTemplate message, const AstRawString* arg0,
421cb0ef41Sopenharmony_ci                       const char* arg1);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  void ReportWarningAt(int start_position, int end_position,
451cb0ef41Sopenharmony_ci                       MessageTemplate message, const char* arg = nullptr);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  bool stack_overflow() const { return stack_overflow_; }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  void set_stack_overflow() {
501cb0ef41Sopenharmony_ci    has_pending_error_ = true;
511cb0ef41Sopenharmony_ci    stack_overflow_ = true;
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  bool has_pending_error() const { return has_pending_error_; }
551cb0ef41Sopenharmony_ci  bool has_pending_warnings() const { return !warning_messages_.empty(); }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // Handle errors detected during parsing.
581cb0ef41Sopenharmony_ci  template <typename IsolateT>
591cb0ef41Sopenharmony_ci  EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
601cb0ef41Sopenharmony_ci  void PrepareErrors(IsolateT* isolate, AstValueFactory* ast_value_factory);
611cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void ReportErrors(Isolate* isolate,
621cb0ef41Sopenharmony_ci                                      Handle<Script> script) const;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  // Handle warnings detected during compilation.
651cb0ef41Sopenharmony_ci  template <typename IsolateT>
661cb0ef41Sopenharmony_ci  void PrepareWarnings(IsolateT* isolate);
671cb0ef41Sopenharmony_ci  void ReportWarnings(Isolate* isolate, Handle<Script> script) const;
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest(Isolate* isolate);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  void set_unidentifiable_error() {
721cb0ef41Sopenharmony_ci    has_pending_error_ = true;
731cb0ef41Sopenharmony_ci    unidentifiable_error_ = true;
741cb0ef41Sopenharmony_ci  }
751cb0ef41Sopenharmony_ci  void clear_unidentifiable_error() {
761cb0ef41Sopenharmony_ci    has_pending_error_ = false;
771cb0ef41Sopenharmony_ci    unidentifiable_error_ = false;
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci  bool has_error_unidentifiable_by_preparser() const {
801cb0ef41Sopenharmony_ci    return unidentifiable_error_;
811cb0ef41Sopenharmony_ci  }
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci private:
841cb0ef41Sopenharmony_ci  class MessageDetails {
851cb0ef41Sopenharmony_ci   public:
861cb0ef41Sopenharmony_ci    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(MessageDetails);
871cb0ef41Sopenharmony_ci    MessageDetails()
881cb0ef41Sopenharmony_ci        : start_position_(-1),
891cb0ef41Sopenharmony_ci          end_position_(-1),
901cb0ef41Sopenharmony_ci          message_(MessageTemplate::kNone) {}
911cb0ef41Sopenharmony_ci    MessageDetails(int start_position, int end_position,
921cb0ef41Sopenharmony_ci                   MessageTemplate message, const AstRawString* arg0)
931cb0ef41Sopenharmony_ci        : start_position_(start_position),
941cb0ef41Sopenharmony_ci          end_position_(end_position),
951cb0ef41Sopenharmony_ci          message_(message),
961cb0ef41Sopenharmony_ci          args_{MessageArgument{arg0}, MessageArgument{}} {}
971cb0ef41Sopenharmony_ci    MessageDetails(int start_position, int end_position,
981cb0ef41Sopenharmony_ci                   MessageTemplate message, const AstRawString* arg0,
991cb0ef41Sopenharmony_ci                   const char* arg1)
1001cb0ef41Sopenharmony_ci        : start_position_(start_position),
1011cb0ef41Sopenharmony_ci          end_position_(end_position),
1021cb0ef41Sopenharmony_ci          message_(message),
1031cb0ef41Sopenharmony_ci          args_{MessageArgument{arg0}, MessageArgument{arg1}} {
1041cb0ef41Sopenharmony_ci      DCHECK_NOT_NULL(arg0);
1051cb0ef41Sopenharmony_ci      DCHECK_NOT_NULL(arg1);
1061cb0ef41Sopenharmony_ci    }
1071cb0ef41Sopenharmony_ci    MessageDetails(int start_position, int end_position,
1081cb0ef41Sopenharmony_ci                   MessageTemplate message, const char* arg0)
1091cb0ef41Sopenharmony_ci        : start_position_(start_position),
1101cb0ef41Sopenharmony_ci          end_position_(end_position),
1111cb0ef41Sopenharmony_ci          message_(message),
1121cb0ef41Sopenharmony_ci          args_{MessageArgument{arg0}, MessageArgument{}} {}
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci    Handle<String> ArgString(Isolate* isolate, int index) const;
1151cb0ef41Sopenharmony_ci    int ArgCount() const {
1161cb0ef41Sopenharmony_ci      int argc = 0;
1171cb0ef41Sopenharmony_ci      for (int i = 0; i < kMaxArgumentCount; i++) {
1181cb0ef41Sopenharmony_ci        if (args_[i].type == kNone) break;
1191cb0ef41Sopenharmony_ci        argc++;
1201cb0ef41Sopenharmony_ci      }
1211cb0ef41Sopenharmony_ci#ifdef DEBUG
1221cb0ef41Sopenharmony_ci      for (int i = argc; i < kMaxArgumentCount; i++) {
1231cb0ef41Sopenharmony_ci        DCHECK_EQ(args_[i].type, kNone);
1241cb0ef41Sopenharmony_ci      }
1251cb0ef41Sopenharmony_ci#endif  // DEBUG
1261cb0ef41Sopenharmony_ci      return argc;
1271cb0ef41Sopenharmony_ci    }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci    MessageLocation GetLocation(Handle<Script> script) const;
1301cb0ef41Sopenharmony_ci    MessageTemplate message() const { return message_; }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci    template <typename IsolateT>
1331cb0ef41Sopenharmony_ci    void Prepare(IsolateT* isolate);
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci   private:
1361cb0ef41Sopenharmony_ci    enum Type { kNone, kAstRawString, kConstCharString, kMainThreadHandle };
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci    void SetString(Handle<String> string, Isolate* isolate);
1391cb0ef41Sopenharmony_ci    void SetString(Handle<String> string, LocalIsolate* isolate);
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci    int start_position_;
1421cb0ef41Sopenharmony_ci    int end_position_;
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci    MessageTemplate message_;
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci    struct MessageArgument final {
1471cb0ef41Sopenharmony_ci      constexpr MessageArgument() : ast_string(nullptr), type(kNone) {}
1481cb0ef41Sopenharmony_ci      explicit constexpr MessageArgument(const AstRawString* s)
1491cb0ef41Sopenharmony_ci          : ast_string(s), type(s == nullptr ? kNone : kAstRawString) {}
1501cb0ef41Sopenharmony_ci      explicit constexpr MessageArgument(const char* s)
1511cb0ef41Sopenharmony_ci          : c_string(s), type(s == nullptr ? kNone : kConstCharString) {}
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci      union {
1541cb0ef41Sopenharmony_ci        const AstRawString* ast_string;
1551cb0ef41Sopenharmony_ci        const char* c_string;
1561cb0ef41Sopenharmony_ci        Handle<String> js_string;
1571cb0ef41Sopenharmony_ci      };
1581cb0ef41Sopenharmony_ci      Type type;
1591cb0ef41Sopenharmony_ci    };
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci    static constexpr int kMaxArgumentCount = 2;
1621cb0ef41Sopenharmony_ci    MessageArgument args_[kMaxArgumentCount];
1631cb0ef41Sopenharmony_ci  };
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  void ThrowPendingError(Isolate* isolate, Handle<Script> script) const;
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  bool has_pending_error_ = false;
1681cb0ef41Sopenharmony_ci  bool stack_overflow_ = false;
1691cb0ef41Sopenharmony_ci  bool unidentifiable_error_ = false;
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  MessageDetails error_details_;
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  std::forward_list<MessageDetails> warning_messages_;
1741cb0ef41Sopenharmony_ci};
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ciextern template void PendingCompilationErrorHandler::PrepareErrors(
1771cb0ef41Sopenharmony_ci    Isolate* isolate, AstValueFactory* ast_value_factory);
1781cb0ef41Sopenharmony_ciextern template void PendingCompilationErrorHandler::PrepareErrors(
1791cb0ef41Sopenharmony_ci    LocalIsolate* isolate, AstValueFactory* ast_value_factory);
1801cb0ef41Sopenharmony_ciextern template void PendingCompilationErrorHandler::PrepareWarnings(
1811cb0ef41Sopenharmony_ci    Isolate* isolate);
1821cb0ef41Sopenharmony_ciextern template void PendingCompilationErrorHandler::PrepareWarnings(
1831cb0ef41Sopenharmony_ci    LocalIsolate* isolate);
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci}  // namespace internal
1861cb0ef41Sopenharmony_ci}  // namespace v8
1871cb0ef41Sopenharmony_ci#endif  // V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_
188