GCC Code Coverage Report


Directory: ./
File: src/parser/parsing_error.cpp
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 62 99 62.6%
Functions: 9 14 64.3%
Branches: 62 116 53.4%

Line Branch Exec Source
1 #include "parsing_error.h"
2
3 #include "ast/magic.h"
4 #include "ast/ops.h"
5 #include "lexer/lexer.h"
6 #include "lexer/unlex.h"
7 #include "utilities/strings.h"
8
9 namespace lython {
10
11 ParsingError::ParsingError(Array<int> expected, Token token, Node* obj, CodeLocation loc):
12 ParsingError(expected, token, loc) {
13 switch (obj->family()) {
14 case NodeFamily::Expression: expr = (ExprNode*)obj;
15 case NodeFamily::Pattern: pat = (Pattern*)obj;
16 case NodeFamily::Statement: stmt = (StmtNode*)obj;
17 default: break;
18 }
19 }
20
21 void add_wip_expr(ParsingError& err, StmtNode* stmt) { err.stmt = stmt; }
22
23 void add_wip_expr(ParsingError& err, ExprNode* expr) { err.expr = expr; }
24
25 void add_wip_expr(ParsingError& err, Node* expr) {
26
4/4
✓ Branch 1 taken 124 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 346 times.
✓ Branch 4 taken 67 times.
565 switch (expr->family()) {
27 124 case NodeFamily::Expression: err.expr = (ExprNode*)expr;
28 152 case NodeFamily::Pattern: err.pat = (Pattern*)expr;
29 498 case NodeFamily::Statement: err.stmt = (StmtNode*)expr;
30 565 default: break;
31 }
32 565 }
33
34 Node* get_expr(ParsingError const& error) {
35
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 67 times.
565 if (error.stmt) {
36 498 return error.stmt;
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.expr) {
38 return error.expr;
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.pat) {
40 return error.pat;
41 }
42 67 return nullptr;
43 }
44
45 CommonAttributes* get_code_loc(ParsingError const& error) {
46
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 67 times.
565 if (error.stmt) {
47
1/2
✓ Branch 0 taken 498 times.
✗ Branch 1 not taken.
498 return error.stmt;
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.expr) {
49 return error.expr;
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.pat) {
51 return error.pat;
52 }
53 67 return nullptr;
54 }
55
56 String get_parent(ParsingError const& error) {
57
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 67 times.
565 if (error.stmt) {
58 498 return shortprint(get_parent(error.stmt));
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.expr) {
60 return shortprint(get_parent(error.expr));
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 } else if (error.pat) {
62 return shortprint(get_parent(error.pat));
63 }
64
65
1/1
✓ Branch 2 taken 67 times.
67 return "<module>";
66 }
67
68 String get_filename(ParsingErrorPrinter* printer) {
69 if (printer->lexer) {
70 return printer->lexer->file_name();
71 }
72 return "<input>";
73 }
74
75 void ParsingErrorPrinter::print_ast(ParsingError const& error,
76 Node* node,
77 CommonAttributes* srcloc) {
78 // Print what we were able to parse
79 {
80 bool written = false;
81
82 if (node) {
83 auto noline_buf = NoNewLine(out);
84 std::ostream noline(&noline_buf);
85 codeline();
86 noline << str(node);
87 noline.flush();
88 written = true;
89 }
90
91 // Print the tokens that we were not able to parse
92 if (error.remaining.size() > 0) {
93 Unlex unlex;
94 unlex.format(out, error.remaining);
95 written = true;
96 }
97
98 if (written) {
99 // Underline error if possible
100 if (srcloc) {
101 underline(*srcloc);
102 } else {
103 underline(error.received_token);
104 }
105 }
106 }
107 }
108
109 void ParsingErrorPrinter::print_tok(ParsingError const& error, CommonAttributes* srcloc) {
110 565 Unlex unlex;
111
112
1/1
✓ Branch 1 taken 565 times.
565 codeline();
113
1/1
✓ Branch 1 taken 565 times.
565 unlex.format(out, error.line);
114
115 // Underline error if possible
116
1/1
✓ Branch 1 taken 565 times.
565 underline(error.received_token);
117 565 }
118
119 void ParsingErrorPrinter::print(ParsingError const& error) {
120
1/1
✓ Branch 1 taken 565 times.
565 String filename = get_filename();
121 565 Node* node = get_expr(error);
122 565 CommonAttributes* srcloc = get_code_loc(error);
123
1/1
✓ Branch 1 taken 565 times.
565 String parent = get_parent(error);
124
125 565 int line = error.received_token.line();
126
127
7/7
✓ Branch 1 taken 565 times.
✓ Branch 4 taken 565 times.
✓ Branch 7 taken 565 times.
✓ Branch 10 taken 565 times.
✓ Branch 13 taken 565 times.
✓ Branch 16 taken 565 times.
✓ Branch 19 taken 565 times.
565 firstline() << "File \"" << filename << "\", line " << line << ", in " << parent;
128
129 // Lython own code loc
130 #if WITH_LOG
131
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
565 if (with_compiler_code_loc) {
132
3/3
✓ Branch 1 taken 565 times.
✓ Branch 4 taken 565 times.
✓ Branch 7 taken 565 times.
565 newline() << error.loc.repr();
133 }
134 #endif
135
136 // Error message
137 if (false) {
138 print_ast(error, node, srcloc);
139 } else {
140
1/1
✓ Branch 1 taken 565 times.
565 print_tok(error, srcloc);
141 }
142
143
3/3
✓ Branch 1 taken 565 times.
✓ Branch 4 taken 565 times.
✓ Branch 7 taken 565 times.
565 errorline() << error.error_kind << ": ";
144
2/2
✓ Branch 1 taken 251 times.
✓ Branch 2 taken 314 times.
565 if (error.expected_tokens.size() > 0) {
145 251 Array<String> toks;
146
2/2
✓ Branch 1 taken 251 times.
✓ Branch 5 taken 251 times.
502 std::transform(std::begin(error.expected_tokens),
147 251 std::end(error.expected_tokens),
148 std::back_inserter(toks),
149 [](int tok) -> String { return to_human_name(tok); });
150
151
2/2
✓ Branch 2 taken 251 times.
✓ Branch 5 taken 251 times.
251 String expected = join("|", toks);
152
153
5/5
✓ Branch 1 taken 251 times.
✓ Branch 4 taken 251 times.
✓ Branch 7 taken 251 times.
✓ Branch 11 taken 251 times.
✓ Branch 14 taken 251 times.
251 out << "Expected: " << expected << " token but got " << to_human_name(error.received_token);
154 251 } else {
155
1/1
✓ Branch 1 taken 314 times.
314 out << error.message;
156 }
157
158
1/1
✓ Branch 1 taken 565 times.
565 end();
159 565 }
160
161 String shortprint(Node const* node) {
162
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 532 times.
631 if (node->kind == NodeKind::FunctionDef) {
163 99 FunctionDef const* fun = static_cast<FunctionDef const*>(node);
164 99 return str(fun->name);
165 }
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
532 if (node->kind == NodeKind::ClassDef) {
167 ClassDef const* def = static_cast<ClassDef const*>(node);
168 return str(def->name);
169 }
170
2/2
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 8 times.
532 if (node->kind == NodeKind::Module) {
171
1/1
✓ Branch 2 taken 524 times.
524 return "<module>";
172 }
173 8 return str(node);
174 }
175
176 Node const* get_parent(Node const* parent) {
177 623 Node const* n = parent->get_parent();
178 623 Node const* p = parent;
179
180
1/2
✓ Branch 0 taken 711 times.
✗ Branch 1 not taken.
711 while (n != nullptr) {
181
182
2/2
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 187 times.
711 if (n->kind == NodeKind::Module) {
183 524 return n;
184 }
185
186
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 88 times.
187 if (n->kind == NodeKind::FunctionDef) {
187 99 return n;
188 }
189 88 p = n;
190 88 n = n->get_parent();
191 }
192
193 return p;
194 }
195
196 } // namespace lython
197