• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ES2PANDA_UTIL_DIAGNOSTIC_ENGINE_H
17 #define ES2PANDA_UTIL_DIAGNOSTIC_ENGINE_H
18 
19 #include <memory>
20 #include <utility>
21 #include "es2panda.h"
22 #include "util/es2pandaMacros.h"
23 #include "generated/diagnostic.h"
24 #include "util/diagnostic.h"
25 #include "lexer/token/sourceLocation.h"
26 
27 namespace ark::es2panda::util {
28 
29 class DiagnosticPrinter {
30 public:
31     DiagnosticPrinter() = default;
32     NO_COPY_SEMANTIC(DiagnosticPrinter);
33     NO_MOVE_SEMANTIC(DiagnosticPrinter);
34     virtual ~DiagnosticPrinter() = default;
35 
36     virtual void Print(const DiagnosticBase &diagnostic) const = 0;
37     virtual void Print(const DiagnosticBase &diagnostic, std::ostream &out) const = 0;
38 };
39 
40 class CLIDiagnosticPrinter : public DiagnosticPrinter {
41 public:
42     CLIDiagnosticPrinter() = default;
43     NO_COPY_SEMANTIC(CLIDiagnosticPrinter);
44     NO_MOVE_SEMANTIC(CLIDiagnosticPrinter);
45     ~CLIDiagnosticPrinter() override = default;
46 
47     void Print(const DiagnosticBase &diagnostic) const override;
48     void Print(const DiagnosticBase &diagnostic, std::ostream &out) const override;
49 };
50 
51 using DiagnosticStorage = std::vector<std::shared_ptr<DiagnosticBase>>;
52 
53 class DiagnosticEngine {
54 public:
DiagnosticEngine()55     explicit DiagnosticEngine() : printer_(std::make_unique<CLIDiagnosticPrinter>())
56     {
57         g_diagnosticEngine = this;
58     }
59     NO_COPY_SEMANTIC(DiagnosticEngine);
60     NO_MOVE_SEMANTIC(DiagnosticEngine);
~DiagnosticEngine()61     ~DiagnosticEngine()
62     {
63         g_diagnosticEngine = nullptr;
64     }
65 
66     // NOTE(schernykh): should be removed
67     const DiagnosticBase &GetAnyError() const;
68 
69     [[nodiscard]] bool IsAnyError() const noexcept;
70 
71     template <typename... T>
CreateSuggestion(T &&...args)72     Suggestion *CreateSuggestion(T &&...args)
73     {
74         return CreateDiagnostic<Suggestion>(std::forward<T>(args)...);
75     }
76 
77     template <typename... T>
LogDiagnostic(T &&...args)78     void LogDiagnostic(T &&...args)
79     {
80         LogDiagnostic<Diagnostic>(std::forward<T>(args)...);
81     }
82 
83     // NOTE(schernykh): should be removed
Log(const ThrowableDiagnostic & error)84     void Log([[maybe_unused]] const ThrowableDiagnostic &error)
85     {
86         printer_->Print(error);
87     };
88 
89     template <typename... T>
LogSyntaxError(T &&...args)90     void LogSyntaxError(T &&...args)
91     {
92         LogThrowableDiagnostic(DiagnosticType::SYNTAX, std::forward<T>(args)...);
93     }
94     template <typename... T>
LogSemanticError(T &&...args)95     void LogSemanticError(T &&...args)
96     {
97         LogThrowableDiagnostic(DiagnosticType::SEMANTIC, std::forward<T>(args)...);
98     }
99     template <typename... T>
LogFatalError(T &&...args)100     void LogFatalError(T &&...args)
101     {
102         LogThrowableDiagnostic(DiagnosticType::FATAL, std::forward<T>(args)...);
103     }
104 
105     // NOTE(schernykh): should not be able from ETS
106     template <typename... T>
ThrowSyntaxError(T &&...args)107     [[noreturn]] void ThrowSyntaxError(T &&...args)
108     {
109         ThrowDiagnostic(DiagnosticType::SYNTAX, std::forward<T>(args)...);
110     }
111     template <typename... T>
ThrowSemanticError(T &&...args)112     [[noreturn]] void ThrowSemanticError(T &&...args)
113     {
114         ThrowDiagnostic(DiagnosticType::SEMANTIC, std::forward<T>(args)...);
115     }
116     template <typename... T>
ThrowFatalError(T &&...args)117     [[noreturn]] void ThrowFatalError(T &&...args)
118     {
119         ThrowDiagnostic(DiagnosticType::FATAL, std::forward<T>(args)...);
120     }
121 
122     void FlushDiagnostic();
123     std::string PrintAndFlushErrorDiagnostic();
SetWError(bool wError)124     void SetWError(bool wError)
125     {
126         wError_ = wError;
127     }
128 
129     const DiagnosticStorage &GetDiagnosticStorage(DiagnosticType type);
130 
131     static void InitializeSignalHandlers();
132 
133 private:
134     template <typename DIAGNOSTIC, typename... T>
CreateDiagnostic(T &&...args)135     DIAGNOSTIC *CreateDiagnostic(T &&...args)
136     {
137         auto diag = std::make_unique<DIAGNOSTIC>(std::forward<T>(args)...);
138         auto type = diag->Type();
139         diagnostics_[type].push_back(std::move(diag));
140         return reinterpret_cast<DIAGNOSTIC *>(diagnostics_[type].back().get());
141     }
142 
143     template <typename DIAGNOSTIC, typename... T>
LogDiagnostic(T &&...args)144     void LogDiagnostic(T &&...args)
145     {
146         CreateDiagnostic<DIAGNOSTIC>(std::forward<T>(args)...);
147     }
148 
149     template <typename... T>
LogThrowableDiagnostic(T &&...args)150     void LogThrowableDiagnostic(T &&...args)
151     {
152         LogDiagnostic<ThrowableDiagnostic>(std::forward<T>(args)...);
153     }
154 
155     template <typename... T>
ThrowDiagnostic(T &&...args)156     [[noreturn]] void ThrowDiagnostic(T &&...args) const
157     {
158         Throw(ThrowableDiagnostic {std::forward<T>(args)...});
159     }
160     [[noreturn]] void Throw(ThrowableDiagnostic diag) const;
161 
162     bool IsError(DiagnosticType type) const;
163     DiagnosticStorage GetAllDiagnostic();
164     DiagnosticStorage GetErrorDiagnostic();
165     void WriteLog(const DiagnosticBase &error);
166 
167 private:
168     std::array<DiagnosticStorage, static_cast<size_t>(DiagnosticType::COUNT)> diagnostics_;
169     std::unique_ptr<const DiagnosticPrinter> printer_;
170     bool wError_ {false};
171 };
172 
173 }  // namespace ark::es2panda::util
174 
175 #endif  // ES2PANDA_UTIL_DIAGNOSTIC_ENGINE_H
176