GCC Code Coverage Report


Directory: ./
File: src/sema/errors.h
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 21 22 95.5%
Functions: 14 16 87.5%
Branches: 15 20 75.0%

Line Branch Exec Source
1 #ifndef LYTHON_SEMA_ERROR_HEADER
2 #define LYTHON_SEMA_ERROR_HEADER
3
4 #include <ostream>
5
6 #include "ast/nodes.h"
7 #include "printer/error_printer.h"
8 #include "sema/builtin.h"
9
10 namespace lython {
11
12 struct SemaError {};
13
14 StmtNode* get_parent_stmt(Node* node);
15
16 struct SemaException: public LythonException {
17 ExprNode* expr = nullptr;
18 StmtNode* stmt = nullptr;
19
20 SemaException(ExprNode* expr): expr(expr), stmt(get_parent_stmt(expr)), cached_message("") {}
21
22 SemaException(StmtNode* stmt, std::string const& msg): stmt(stmt), cached_message(msg) {}
23
24 SemaException(std::string const& msg): cached_message(msg) {}
25
26 SemaException(): cached_message("") {}
27
28 virtual const char* what() const LY_NOEXCEPT override final {
29 272 generate_message();
30 272 return cached_message.c_str();
31 }
32
33 void generate_message() const {
34
2/2
✓ Branch 1 taken 145 times.
✓ Branch 2 taken 127 times.
272 if (cached_message.size() > 0) {
35 145 return;
36 }
37
38
1/2
✓ Branch 1 taken 127 times.
✗ Branch 2 not taken.
127 cached_message = message();
39 }
40
41 void set_node(Node* node) {
42
5/6
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 305 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 305 times.
✓ Branch 6 taken 14 times.
319 if (node && node->family() == NodeFamily::Expression) {
43 305 set_expr((ExprNode*)node);
44 }
45
46
5/6
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 305 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 305 times.
319 if (node && node->family() == NodeFamily::Statement) {
47 14 set_stmt((StmtNode*)node);
48 }
49 319 }
50
51 void set_expr(ExprNode* expression) {
52 305 expr = expression;
53 305 stmt = get_parent_stmt(expr);
54 305 }
55
56 void set_stmt(StmtNode* statement) { stmt = statement; }
57
58 virtual std::string message() const = 0;
59
60 mutable std::string cached_message;
61 };
62
63 /*
64 *
65 * Examples
66 * --------
67 * >>> class Name:
68 * ... x = 1
69 * ...
70 * >>> a = Name()
71 * >>> a.n
72 * Traceback (most recent call last):
73 * File "<stdin>", line 1, in <module>
74 * AttributeError: 'Name' object has no attribute 'n'
75 */
76 struct AttributeError: public SemaException {
77 AttributeError(ClassDef* obj, StringRef attr):
78
1/1
✓ Branch 2 taken 2 times.
2 obj(obj), attr(attr) //
79 2 {}
80
81 std::string message() const override;
82
83 static std::string message(String const& name, String const& attr);
84
85 ClassDef* obj;
86 StringRef attr;
87 };
88
89 /*
90 * Examples
91 * --------
92 * >>> x
93 * Traceback (most recent call last):
94 * File "<stdin>", line 1, in <module>
95 * NameError: name 'x' is not defined
96 */
97 struct NameError: public SemaException {
98 NameError(Node* code, StringRef name): code(code), name(name) {}
99
100 std::string message() const override;
101
102 Node* code;
103 StringRef name;
104 };
105
106 /*
107 * Examples
108 * --------
109 * >>> x = 1
110 * >>> x(1)
111 * Traceback (most recent call last):
112 * File "<stdin>", line 1, in <module>
113 * TypeError: 'int' object is not callable
114 *
115 */
116 struct TypeError: public SemaException {
117 TypeError(std::string const& msg): SemaException(msg) {}
118
119 TypeError(
120 21 ExprNode* lhs, TypeExpr* lhs_t, ExprNode* rhs, TypeExpr* rhs_t, CodeLocation const& loc):
121 21 lhs_v(lhs),
122 21 lhs_t(lhs_t), rhs_v(rhs), rhs_t(rhs_t) {}
123
124 std::string message() const override;
125
126 static std::string
127 message(String const& lhs_v, String const& lhs_t, String const& rhs_v, String const& rhs_t);
128
129 // Source code info
130 ExprNode* lhs_v = nullptr;
131 TypeExpr* lhs_t = nullptr;
132 ExprNode* rhs_v = nullptr;
133 TypeExpr* rhs_t = nullptr;
134 };
135
136 struct UnsupportedOperand: public SemaException {
137 UnsupportedOperand(String const& str, TypeExpr* lhs_t, TypeExpr* rhs_t):
138
1/1
✓ Branch 2 taken 35 times.
35 operand(str), lhs_t(lhs_t), rhs_t(rhs_t) {}
139
140 std::string message() const override;
141
142 static std::string message(String const& op, String const& lhs_t, String const& rhs_t);
143
144 String operand;
145 TypeExpr* lhs_t = nullptr;
146 TypeExpr* rhs_t = nullptr;
147 };
148
149 struct RecursiveDefinition: public SemaException {
150 RecursiveDefinition(String const& str, ExprNode* fun, ClassDef* cls):
151 msg(str), fun(fun), cls(cls) {}
152
153 std::string message() const override;
154
155 static std::string message(ExprNode const* lhs_t, ClassDef const* rhs_t);
156
157 String msg;
158 ExprNode* fun = nullptr;
159 ClassDef* cls = nullptr;
160 };
161
162 struct ModuleNotFoundError: public SemaException {
163 ModuleNotFoundError(StringRef const& mod): module(mod) {}
164
165 std::string message() const override;
166
167 static std::string message(String const& module);
168
169 StringRef module;
170 };
171
172 struct ImportError: public SemaException {
173 ImportError(StringRef const& mod, StringRef const& name): module(mod), name(name) {}
174
175 std::string message() const override;
176
177 static std::string message(String const& module, String const& name);
178
179 StringRef module;
180 StringRef name;
181 };
182
183 struct SemaErrorPrinter: public BaseErrorPrinter {
184 SemaErrorPrinter(std::ostream& out, class AbstractLexer* lexer = nullptr):
185 170 BaseErrorPrinter(out, lexer) //
186 170 {}
187
188 void print(SemaException const& err);
189 };
190
191 } // namespace lython
192
193 #endif
194