• 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_H
17 #define ES2PANDA_UTIL_DIAGNOSTIC_H
18 
19 #include <initializer_list>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 #include "util/es2pandaMacros.h"
24 #include "util/ustring.h"
25 #include "generated/tokenType.h"
26 
27 namespace ark::es2panda::diagnostic {
28 class DiagnosticKind;
29 }  // namespace ark::es2panda::diagnostic
30 
31 namespace ark::es2panda::checker {
32 class Type;
33 class Signature;
34 }  // namespace ark::es2panda::checker
35 
36 namespace ark::es2panda::lexer {
37 class SourcePosition;
38 class SourceLocation;
39 }  // namespace ark::es2panda::lexer
40 
41 namespace ark::es2panda::util {
42 
43 enum DiagnosticType {
44     BEGIN = 0,
45     FATAL = BEGIN,
46     SYNTAX,
47     SEMANTIC,
48     WARNING,
49     PLUGIN_ERROR,
50     PLUGIN_WARNING,
51     DECLGEN_ETS2TS_ERROR,
52     DECLGEN_ETS2TS_WARNING,
53     ARKTS_CONFIG_ERROR,
54     SUGGESTION,
55     ISOLATED_DECLGEN,
56     COUNT,
57     INVALID = COUNT
58 };
59 
60 const char *DiagnosticTypeToString(DiagnosticType type);
61 
62 class DiagnosticBase {
63 public:
64     explicit DiagnosticBase(std::string_view file = "", size_t line = 0, size_t offset = 0)
file_(file)65         : file_(file), line_(line), offset_(offset)
66     {
67     }
68 
69     explicit DiagnosticBase(const lexer::SourcePosition &pos);
70     explicit DiagnosticBase(const lexer::SourceLocation &loc);
71 
72     DEFAULT_COPY_SEMANTIC(DiagnosticBase);
73     DEFAULT_MOVE_SEMANTIC(DiagnosticBase);
74     virtual ~DiagnosticBase() = default;
75 
76     virtual DiagnosticType Type() const = 0;
77     virtual std::string Message() const = 0;
78 
79     bool operator<(const DiagnosticBase &rhs) const;
80     bool operator==(const DiagnosticBase &rhs) const;
81 
File()82     const std::string &File() const
83     {
84         return file_;
85     }
86 
GetLoc()87     std::pair<size_t, size_t> GetLoc() const
88     {
89         return {line_, offset_};
90     }
91 
Line()92     size_t Line() const
93     {
94         return line_;
95     }
96 
Offset()97     size_t Offset() const
98     {
99         return offset_;
100     }
101 
102 private:
103     std::string file_;
104     size_t line_ {};
105     size_t offset_ {};
106 };
107 
108 class AsSrc {
109 public:
AsSrc(const checker::Type * type)110     explicit AsSrc(const checker::Type *type) : type_(const_cast<checker::Type *>(type)) {}
111 
GetType()112     const checker::Type *GetType() const
113     {
114         return type_;
115     }
116 
117 private:
118     checker::Type *type_;
119 };
120 
121 using DiagnosticMessageElement =
122     std::variant<std::string, std::string_view, const char *const, StringView, size_t, lexer::TokenType, AsSrc,
123                  const checker::Type *const, const checker::Signature *const>;
124 using DiagnosticMessageParams = std::vector<DiagnosticMessageElement>;
125 
126 struct DiagnosticWithParams {
127     const diagnostic::DiagnosticKind &kind;     // NOLINT(readability-identifier-naming)
128     const DiagnosticMessageParams params = {};  // NOLINT(readability-identifier-naming)
129 };
130 
131 // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
132 class ThrowableDiagnostic : public DiagnosticBase, public std::exception {
133 public:
134     ThrowableDiagnostic() = default;
135     ThrowableDiagnostic(DiagnosticType type, std::string_view message, std::string_view file = "", size_t line = 0,
136                         size_t offset = 0)
DiagnosticBase(file,line,offset)137         : DiagnosticBase(file, line, offset), type_(type), message_(message)
138     {
139     }
ThrowableDiagnostic(DiagnosticType type,std::string_view message,const lexer::SourcePosition & pos)140     ThrowableDiagnostic(DiagnosticType type, std::string_view message, const lexer::SourcePosition &pos)
141         : DiagnosticBase(pos), type_(type), message_(message)
142     {
143     }
ThrowableDiagnostic(DiagnosticType type,std::string_view message,const lexer::SourceLocation & loc)144     ThrowableDiagnostic(DiagnosticType type, std::string_view message, const lexer::SourceLocation &loc)
145         : DiagnosticBase(loc), type_(type), message_(message)
146     {
147     }
148     ThrowableDiagnostic(DiagnosticType type, const DiagnosticMessageParams &params, const lexer::SourcePosition &pos);
149     ThrowableDiagnostic(DiagnosticType type, const DiagnosticMessageParams &params, const lexer::SourceLocation &loc);
150     ThrowableDiagnostic(DiagnosticType type, const DiagnosticMessageParams &params, std::string_view file = "",
151                         size_t line = 0, size_t offset = 0);
152     ThrowableDiagnostic(DiagnosticType type, const diagnostic::DiagnosticKind &diagnosticKind,
153                         const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos);
154 
155     DEFAULT_COPY_SEMANTIC(ThrowableDiagnostic);
156     DEFAULT_MOVE_SEMANTIC(ThrowableDiagnostic);
157     ~ThrowableDiagnostic() override = default;
158 
Type()159     DiagnosticType Type() const override
160     {
161         return type_;
162     }
163 
Message()164     std::string Message() const override
165     {
166         return message_;
167     }
168 
169 private:
170     DiagnosticType type_ {DiagnosticType::INVALID};
171     std::string message_ {};
172 };
173 
174 class Suggestion : public DiagnosticBase {
175 public:
176     explicit Suggestion(const diagnostic::DiagnosticKind *kind, std::vector<std::string> &params,
177                         const char *substitutionCode, const lexer::SourceRange *range);
178 
SourceRange()179     const lexer::SourceRange *SourceRange() const
180     {
181         return range_;
182     }
183 
SubstitutionCode()184     std::string SubstitutionCode() const
185     {
186         return substitutionCode_;
187     }
188 
Message()189     std::string Message() const override
190     {
191         return message_;
192     }
193 
194     DiagnosticType Type() const override;
195 
196 private:
197     const diagnostic::DiagnosticKind *kind_;
198     const std::string substitutionCode_;
199     const std::string message_;
200     const lexer::SourceRange *range_;
201 };
202 
203 class Diagnostic : public DiagnosticBase {
204 public:
205     explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind,
206                         const util::DiagnosticMessageParams &diagnosticParams);
207     explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind,
208                         const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos);
209     explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind,
210                         const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos,
211                         Suggestion *suggestion);
212     explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind,
213                         const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos,
214                         std::initializer_list<Suggestion *> suggestions);
215 
216     NO_COPY_SEMANTIC(Diagnostic);
217     DEFAULT_MOVE_SEMANTIC(Diagnostic);
218     ~Diagnostic() override = default;
219 
220     DiagnosticType Type() const override;
221     std::string Message() const override;
222 
HasSuggestions()223     bool HasSuggestions() const
224     {
225         return suggestions_ != nullptr;
226     }
227 
Suggestion()228     const std::vector<class Suggestion *> &Suggestion() const
229     {
230         return *suggestions_;
231     }
232 
233 private:
234     const diagnostic::DiagnosticKind *diagnosticKind_;
235     std::vector<std::string> diagnosticParams_ {};
236     std::unique_ptr<std::vector<class Suggestion *>> suggestions_ {};
237 };
238 }  // namespace ark::es2panda::util
239 
240 #endif  // ES2PANDA_UTIL_DIAGNOSTICE_H
241