Skip to content

Commit 5f53ad2

Browse files
XX Create new structure FileLocations to handle imported file errors
1 parent ce4612d commit 5f53ad2

File tree

11 files changed

+203
-141
lines changed

11 files changed

+203
-141
lines changed

src/bin/lpython.cpp

Lines changed: 56 additions & 48 deletions
Large diffs are not rendered by default.

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
380380
void debug_get_line_column(const uint32_t &loc_first,
381381
uint32_t &line, uint32_t &column) {
382382
LocationManager lm;
383-
lm.in_filename = infile;
383+
LocationManager::FileLocations fl;
384+
fl.in_filename = infile;
385+
lm.files.push_back(fl);
384386
lm.init_simple(LFortran::read_file(infile));
385-
lm.pos_to_linecol(lm.output_to_input_pos(loc_first, false), line, column);
387+
lm.pos_to_linecol(lm.output_to_input_pos(loc_first, false), line, column, fl.in_filename);
386388
}
387389

388390
template <typename T>

src/libasr/diagnostics.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ bool Diagnostics::has_error() const {
6161
return false;
6262
}
6363

64-
std::string Diagnostics::render(const std::string &input,
65-
const LocationManager &lm, const CompilerOptions &compiler_options) {
64+
std::string Diagnostics::render(const std::string &/*input1*/,
65+
LocationManager &lm, const CompilerOptions &compiler_options) {
6666
std::string out;
67+
std::string input;
6768
for (auto &d : this->diagnostics) {
6869
if (compiler_options.no_warnings && d.level != Level::Error) {
6970
continue;
7071
}
72+
// read_file(lm.files.back().in_filename, input);
7173
if (compiler_options.error_format == "human") {
7274
out += render_diagnostic_human(d, input, lm,
7375
compiler_options.use_colors,
@@ -78,6 +80,7 @@ std::string Diagnostics::render(const std::string &input,
7880
} else {
7981
throw LCompilersException("Error format not supported.");
8082
}
83+
// lm.files.pop_back();
8184
}
8285
if (compiler_options.error_format == "human") {
8386
if (this->diagnostics.size() > 0 && !compiler_options.no_error_banner) {
@@ -109,12 +112,14 @@ std::string get_line(std::string str, int n)
109112
}
110113

111114
void populate_span(diag::Span &s, const LocationManager &lm,
112-
const std::string &input) {
115+
const std::string &/*input*/) {
113116
lm.pos_to_linecol(lm.output_to_input_pos(s.loc.first, false),
114-
s.first_line, s.first_column);
117+
s.first_line, s.first_column, s.filename);
115118
lm.pos_to_linecol(lm.output_to_input_pos(s.loc.last, true),
116-
s.last_line, s.last_column);
117-
s.filename = lm.in_filename;
119+
s.last_line, s.last_column, s.filename);
120+
std::string input;
121+
// std::cout << s.filename << "\n";
122+
read_file(s.filename, input);
118123
for (uint32_t i = s.first_line; i <= s.last_line; i++) {
119124
s.source_code.push_back(get_line(input, i));
120125
}
@@ -178,7 +183,7 @@ std::string render_diagnostic_human(const Diagnostic &d, bool use_colors) {
178183
std::string type_color = "";
179184
switch (d.level) {
180185
case (Level::Error):
181-
primary_color = red_bold;
186+
primary_color = red_bold;
182187
type_color = primary_color;
183188
switch (d.stage) {
184189
case (Stage::CPreprocessor):
@@ -205,17 +210,17 @@ std::string render_diagnostic_human(const Diagnostic &d, bool use_colors) {
205210
}
206211
break;
207212
case (Level::Warning):
208-
primary_color = yellow_bold;
213+
primary_color = yellow_bold;
209214
type_color = primary_color;
210215
message_type = "warning";
211216
break;
212217
case (Level::Note):
213-
primary_color = bold;
218+
primary_color = bold;
214219
type_color = primary_color;
215220
message_type = "note";
216221
break;
217222
case (Level::Help):
218-
primary_color = bold;
223+
primary_color = bold;
219224
type_color = primary_color;
220225
message_type = "help";
221226
break;
@@ -287,6 +292,7 @@ std::string render_diagnostic_human(const Diagnostic &d, bool use_colors) {
287292
// and start a new one:
288293
s0 = s2;
289294
if (s0.first_line == s0.last_line) {
295+
out << "here\n";
290296
out << std::string(line_num_width+1, ' ') << blue_bold << "|"
291297
<< reset << std::endl;
292298
std::string line = s0.source_code[0];

src/libasr/diagnostics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ struct Diagnostics {
114114
std::vector<Diagnostic> diagnostics;
115115

116116
std::string render(const std::string &input,
117-
const LocationManager &lm, const CompilerOptions &compiler_options);
117+
LocationManager &lm, const CompilerOptions &compiler_options);
118118

119119
// Returns true iff diagnostics contains at least one error message
120120
bool has_error() const;

src/libasr/location.h

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <cstdint>
55
#include <vector>
6+
#include <iostream>
67

78
namespace LFortran
89
{
@@ -94,50 +95,63 @@ struct LocationManager {
9495
//
9596
//
9697
//
97-
std::vector<uint32_t> out_start; // consecutive intervals in the output code
98-
std::vector<uint32_t> in_start; // start + size in the original code
99-
std::vector<uint32_t> in_newlines; // position of all \n in the original code
98+
struct FileLocations {
99+
std::vector<uint32_t> out_start; // consecutive intervals in the output code
100+
std::vector<uint32_t> in_start; // start + size in the original code
101+
std::vector<uint32_t> in_newlines; // position of all \n in the original code
100102

101-
// For preprocessor (if preprocessor==true).
102-
// TODO: design a common structure, that also works with #include, that
103-
// has these mappings for each file
104-
bool preprocessor = false;
105-
std::string in_filename;
106-
uint32_t current_line=0;
107-
std::vector<uint32_t> out_start0; // consecutive intervals in the output code
108-
std::vector<uint32_t> in_start0; // start + size in the original code
109-
std::vector<uint32_t> in_size0; // Size of the `in` interval
110-
std::vector<uint32_t> interval_type0; // 0 .... 1:1; 1 ... many to many;
111-
std::vector<uint32_t> in_newlines0; // position of all \n in the original code
112-
// std::vector<uint32_t> filename_id; // file name for each interval, ID
113-
// std::vector<std::string> filenames; // filenames lookup for an ID
103+
// For preprocessor (if preprocessor==true).
104+
// TODO: design a common structure, that also works with #include, that
105+
// has these mappings for each file
106+
bool preprocessor = false;
107+
std::string in_filename;
108+
uint32_t current_line=0;
109+
std::vector<uint32_t> out_start0; // consecutive intervals in the output code
110+
std::vector<uint32_t> in_start0; // start + size in the original code
111+
std::vector<uint32_t> in_size0; // Size of the `in` interval
112+
std::vector<uint32_t> interval_type0; // 0 .... 1:1; 1 ... many to many;
113+
std::vector<uint32_t> in_newlines0; // position of all \n in the original code
114+
};
115+
std::vector<FileLocations> files;
116+
std::vector<uint32_t> file_ends; // position of all ends of files
117+
// For a given Location we use the `file_ends` and bisection to determine
118+
// the file (index) which the location is from. Then we use this index into
119+
// the `files` vector and use `in_newlines` and other information to
120+
// determine the line and column inside this file, and the `in_filename`
121+
// field to determine the filename. This happens when the diagnostic is
122+
// printed. The `pos_to_linecol` function below should be modified to
123+
// return line, column and the filename:
124+
//
125+
// void pos_to_linecol(uint32_t position, uint32_t &line, uint32_t &col,
126+
// std::string &filename) const;
114127

115128
// Converts a position in the output code to a position in the original code
116129
// Every character in the output code has a corresponding location in the
117130
// original code, so this function always succeeds
118131
uint32_t output_to_input_pos(uint32_t out_pos, bool show_last) const {
119-
if (out_start.size() == 0) return 0;
120-
uint32_t interval = bisection(out_start, out_pos)-1;
121-
uint32_t rel_pos = out_pos - out_start[interval];
122-
uint32_t in_pos = in_start[interval] + rel_pos;
123-
if (preprocessor) {
132+
uint32_t index = bisection(file_ends, out_pos);
133+
if (files[index].out_start.size() == 0) return 0;
134+
uint32_t interval = bisection(files[index].out_start, out_pos)-1;
135+
uint32_t rel_pos = out_pos - files[index].out_start[interval];
136+
uint32_t in_pos = files[index].in_start[interval] + rel_pos;
137+
if (files[index].preprocessor) {
124138
// If preprocessor was used, do one more remapping
125-
uint32_t interval0 = bisection(out_start0, in_pos)-1;
126-
if (interval_type0[interval0] == 0) {
139+
uint32_t interval0 = bisection(files[index].out_start0, in_pos)-1;
140+
if (files[index].interval_type0[interval0] == 0) {
127141
// 1:1 interval
128-
uint32_t rel_pos0 = in_pos - out_start0[interval0];
129-
uint32_t in_pos0 = in_start0[interval0] + rel_pos0;
142+
uint32_t rel_pos0 = in_pos - files[index].out_start0[interval0];
143+
uint32_t in_pos0 = files[index].in_start0[interval0] + rel_pos0;
130144
return in_pos0;
131145
} else {
132146
// many to many interval
133147
uint32_t in_pos0;
134-
if (in_pos == out_start0[interval0+1]-1 || show_last) {
148+
if (in_pos == files[index].out_start0[interval0+1]-1 || show_last) {
135149
// The end of the interval in "out" code
136150
// Return the end of the interval in "in" code
137-
in_pos0 = in_start0[interval0]+in_size0[interval0]-1;
151+
in_pos0 = files[index].in_start0[interval0]+files[index].in_size0[interval0]-1;
138152
} else {
139153
// Otherwise return the beginning of the interval in "in"
140-
in_pos0 = in_start0[interval0];
154+
in_pos0 = files[index].in_start0[interval0];
141155
}
142156
return in_pos0;
143157
}
@@ -150,12 +164,17 @@ struct LocationManager {
150164
// `position` starts from 0
151165
// `line` and `col` starts from 1
152166
// `in_newlines` starts from 0
153-
void pos_to_linecol(uint32_t position, uint32_t &line, uint32_t &col) const {
167+
void pos_to_linecol(uint32_t position, uint32_t &line, uint32_t &col,
168+
std::string &filename) const {
169+
uint32_t index = bisection(file_ends, position);
170+
for (auto &x: file_ends) std::cout << x << "\n";
171+
std::cout << position << ":\n";
172+
filename = files[index].in_filename;
154173
const std::vector<uint32_t> *newlines;
155-
if (preprocessor) {
156-
newlines = &in_newlines0;
174+
if (files[index].preprocessor) {
175+
newlines = &files[index].in_newlines0;
157176
} else {
158-
newlines = &in_newlines;
177+
newlines = &files[index].in_newlines;
159178
}
160179
int32_t interval = bisection(*newlines, position);
161180
if (interval >= 1 && position == (*newlines)[interval-1]) {
@@ -179,9 +198,9 @@ struct LocationManager {
179198

180199
void init_simple(const std::string &input) {
181200
uint32_t n = input.size();
182-
out_start = {0, n};
183-
in_start = {0, n};
184-
get_newlines(input, in_newlines);
201+
files.back().out_start = {0, n};
202+
files.back().in_start = {0, n};
203+
get_newlines(input, files.back().in_newlines);
185204
}
186205

187206
};

0 commit comments

Comments
 (0)