Skip to content

Commit a9e9987

Browse files
committed
Merge remote-tracking branch 'origin/main' into nulls-last
2 parents 1e182e7 + 6768560 commit a9e9987

File tree

14 files changed

+359
-267
lines changed

14 files changed

+359
-267
lines changed

prql-compiler/prqlc/src/cli.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::str::FromStr;
1111
use prql_compiler::semantic::{self, reporting::*};
1212
use prql_compiler::{ast::pl::Lineage, pl_to_prql};
1313
use prql_compiler::{downcast, Options, Target};
14-
use prql_compiler::{pl_to_rq_tree, prql_to_pl, prql_to_pl_tree, rq_to_sql, FileTree, Span};
14+
use prql_compiler::{pl_to_rq_tree, prql_to_pl, prql_to_pl_tree, rq_to_sql, SourceTree, Span};
1515

1616
use crate::watch;
1717

@@ -177,7 +177,7 @@ impl Command {
177177
Ok(())
178178
}
179179

180-
fn execute<'a>(&self, sources: &'a FileTree, main_path: &'a str) -> Result<Vec<u8>> {
180+
fn execute<'a>(&self, sources: &'a SourceTree, main_path: &'a str) -> Result<Vec<u8>> {
181181
let main_path = main_path
182182
.split('.')
183183
.filter(|x| !x.is_empty())
@@ -193,7 +193,7 @@ impl Command {
193193
}
194194
}
195195
Command::Format(_) => {
196-
let (_, source) = sources.files.clone().into_iter().exactly_one()?;
196+
let (_, source) = sources.sources.clone().into_iter().exactly_one()?;
197197
let ast = prql_to_pl(&source)?;
198198

199199
pl_to_prql(ast)?.as_bytes().to_vec()
@@ -206,7 +206,7 @@ impl Command {
206206
.map_err(|e| e.composed(sources, true))?;
207207

208208
let mut out = Vec::new();
209-
for (source_id, source) in &sources.files {
209+
for (source_id, source) in &sources.sources {
210210
let source_id = source_id.to_str().unwrap().to_string();
211211
out.extend(label_references(&context, source_id, source.clone()));
212212
}
@@ -215,7 +215,7 @@ impl Command {
215215
out
216216
}
217217
Command::Annotate(_) => {
218-
let (_, source) = sources.files.clone().into_iter().exactly_one()?;
218+
let (_, source) = sources.sources.clone().into_iter().exactly_one()?;
219219

220220
// TODO: potentially if there is code performing a role beyond
221221
// presentation, it should be a library function; and we could
@@ -287,7 +287,7 @@ impl Command {
287287
})
288288
}
289289

290-
fn read_input(&mut self) -> Result<(FileTree, String)> {
290+
fn read_input(&mut self) -> Result<(SourceTree, String)> {
291291
// Possibly this should be called by the relevant subcommands passing in
292292
// `input`, rather than matching on them and grabbing `input` from
293293
// `self`? But possibly if everything moves to `io_args`, then this is
@@ -376,7 +376,7 @@ mod clio_extended {
376376
use std::path::Path;
377377

378378
use clap::builder::TypedValueParser;
379-
use prql_compiler::FileTree;
379+
use prql_compiler::SourceTree;
380380
use walkdir::WalkDir;
381381

382382
#[derive(Debug)]
@@ -427,7 +427,7 @@ mod clio_extended {
427427
}
428428
}
429429

430-
pub fn read_to_tree(&mut self) -> anyhow::Result<FileTree<String>> {
430+
pub fn read_to_tree(&mut self) -> anyhow::Result<SourceTree<String>> {
431431
let mut only_file = String::new();
432432

433433
match self {
@@ -438,7 +438,7 @@ mod clio_extended {
438438
let root_path = Path::new(root_path);
439439

440440
// special case: actually walk the dirs
441-
let mut files = HashMap::new();
441+
let mut sources = HashMap::new();
442442
for entry in WalkDir::new(root_path) {
443443
let entry = entry?;
444444
let path = entry.path();
@@ -447,18 +447,16 @@ mod clio_extended {
447447
let file_contents = fs::read_to_string(path)?;
448448
let path = path.strip_prefix(root_path)?.to_path_buf();
449449

450-
files.insert(path, file_contents);
450+
sources.insert(path, file_contents);
451451
}
452452
}
453453

454-
return Ok(FileTree { files });
454+
return Ok(SourceTree::new(sources));
455455
}
456456
};
457457

458458
let path = Path::new(self.path()).to_path_buf();
459-
Ok(FileTree {
460-
files: [(path, only_file)].into(),
461-
})
459+
Ok(SourceTree::single(path, only_file))
462460
}
463461
}
464462

@@ -646,16 +644,13 @@ group a_column (take 10 | sort b_column | derive {the_number = rank, last = lag
646644
hide_signature_comment: true,
647645
target: "sql.any".to_string(),
648646
},
649-
&FileTree {
650-
files: [
651-
("_project.prql".into(), "orders.x | select y".to_string()),
652-
(
653-
"orders.prql".into(),
654-
"let x = (from z | select {y, u})".to_string(),
655-
),
656-
]
657-
.into(),
658-
},
647+
&SourceTree::new([
648+
("_project.prql".into(), "orders.x | select y".to_string()),
649+
(
650+
"orders.prql".into(),
651+
"let x = (from z | select {y, u})".to_string(),
652+
),
653+
]),
659654
"main",
660655
)
661656
.unwrap();
@@ -689,7 +684,7 @@ group a_column (take 10 | sort b_column | derive {the_number = rank, last = lag
689684
.unwrap();
690685

691686
assert_display_snapshot!(String::from_utf8(output).unwrap().trim(), @r###"
692-
files:
687+
sources:
693688
'':
694689
- name: main
695690
VarDef:
@@ -712,6 +707,8 @@ group a_column (take 10 | sort b_column | derive {the_number = rank, last = lag
712707
- y
713708
ty_expr: null
714709
kind: Main
710+
source_ids:
711+
1: ''
715712
"###);
716713
}
717714
#[test]
@@ -816,12 +813,12 @@ group a_column (take 10 | sort b_column | derive {the_number = rank, last = lag
816813
args:
817814
- kind:
818815
ColumnRef: 2
819-
span: span-chars-47-53
816+
span: 1:47-53
820817
- kind:
821818
Literal:
822819
Integer: 0
823-
span: span-chars-56-57
824-
span: span-chars-47-57
820+
span: 1:56-57
821+
span: 1:47-57
825822
- Sort:
826823
- direction: Asc
827824
column: 2

prql-compiler/src/error.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
pub use anyhow::Result;
22

33
use ariadne::{Cache, Config, Label, Report, ReportKind, Source};
4-
use itertools::Itertools;
54
use serde::de::Visitor;
65
use serde::{Deserialize, Serialize};
76

@@ -11,12 +10,14 @@ use std::fmt::{self, Debug, Display, Formatter};
1110
use std::ops::{Add, Range};
1211
use std::path::PathBuf;
1312

14-
use crate::FileTree;
13+
use crate::SourceTree;
1514

1615
#[derive(Clone, PartialEq, Eq, Copy)]
1716
pub struct Span {
1817
pub start: usize,
1918
pub end: usize,
19+
20+
pub source_id: usize,
2021
}
2122

2223
#[derive(Debug, Clone)]
@@ -251,21 +252,23 @@ impl ErrorMessages {
251252
}
252253

253254
/// Computes message location and builds the pretty display.
254-
pub fn composed(mut self, sources: &FileTree, color: bool) -> Self {
255+
pub fn composed(mut self, sources: &SourceTree, color: bool) -> Self {
255256
let mut cache = FileTreeCache::new(sources);
256257

257-
// TODO: get id from the error
258-
let Ok((id, _)) = sources.files.iter().exactly_one() else {
259-
return self;
260-
};
261-
262258
for e in &mut self.inner {
263-
let Ok(source) = cache.fetch(id) else {
259+
let Some(span) = e.span else {
260+
continue;
261+
};
262+
let Some(source_path) = sources.source_ids.get(&span.source_id) else {
263+
continue;
264+
};
265+
266+
let Ok(source) = cache.fetch(source_path) else {
264267
continue
265268
};
266269
e.location = e.compose_location(source);
267270

268-
e.display = e.compose_display(id.clone(), &mut cache, color);
271+
e.display = e.compose_display(source_path.clone(), &mut cache, color);
269272
}
270273
self
271274
}
@@ -274,17 +277,17 @@ impl ErrorMessages {
274277
impl ErrorMessage {
275278
fn compose_display(
276279
&self,
277-
source_id: PathBuf,
280+
source_path: PathBuf,
278281
cache: &mut FileTreeCache,
279282
color: bool,
280283
) -> Option<String> {
281284
let config = Config::default().with_color(color);
282285

283286
let span = Range::from(self.span?);
284287

285-
let mut report = Report::build(ReportKind::Error, source_id.clone(), span.start)
288+
let mut report = Report::build(ReportKind::Error, source_path.clone(), span.start)
286289
.with_config(config)
287-
.with_label(Label::new((source_id, span)).with_message(&self.reason));
290+
.with_label(Label::new((source_path, span)).with_message(&self.reason));
288291

289292
if let Some(code) = &self.code {
290293
report = report.with_code(code);
@@ -312,11 +315,11 @@ impl ErrorMessage {
312315
}
313316

314317
struct FileTreeCache<'a> {
315-
file_tree: &'a FileTree,
318+
file_tree: &'a SourceTree,
316319
cache: HashMap<PathBuf, Source>,
317320
}
318321
impl<'a> FileTreeCache<'a> {
319-
fn new(file_tree: &'a FileTree) -> Self {
322+
fn new(file_tree: &'a SourceTree) -> Self {
320323
FileTreeCache {
321324
file_tree,
322325
cache: HashMap::new(),
@@ -326,7 +329,7 @@ impl<'a> FileTreeCache<'a> {
326329

327330
impl<'a> Cache<PathBuf> for FileTreeCache<'a> {
328331
fn fetch(&mut self, id: &PathBuf) -> Result<&Source, Box<dyn fmt::Debug + '_>> {
329-
let file_contents = match self.file_tree.files.get(id) {
332+
let file_contents = match self.file_tree.sources.get(id) {
330333
Some(v) => v,
331334
None => return Err(Box::new(format!("Unknown file `{id:?}`"))),
332335
};
@@ -369,13 +372,14 @@ impl From<Span> for Range<usize> {
369372
}
370373
}
371374

372-
impl Add<Span> for Span {
375+
impl Add<usize> for Span {
373376
type Output = Span;
374377

375-
fn add(self, rhs: Span) -> Span {
378+
fn add(self, rhs: usize) -> Span {
376379
Span {
377-
start: self.start.min(rhs.start),
378-
end: self.end.max(rhs.end),
380+
start: self.start + rhs,
381+
end: self.end + rhs,
382+
source_id: self.source_id,
379383
}
380384
}
381385
}
@@ -420,7 +424,7 @@ impl<T, E: WithErrorInfo> WithErrorInfo for Result<T, E> {
420424

421425
impl Debug for Span {
422426
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
423-
write!(f, "span-chars-{}-{}", self.start, self.end)
427+
write!(f, "{}:{}-{}", self.source_id, self.start, self.end)
424428
}
425429
}
426430

@@ -445,7 +449,7 @@ impl<'de> Deserialize<'de> for Span {
445449
type Value = Span;
446450

447451
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
448-
write!(f, "A span string of form `span-chars-x-y`")
452+
write!(f, "A span string of form `file_id:x-y`")
449453
}
450454

451455
fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
@@ -454,18 +458,27 @@ impl<'de> Deserialize<'de> for Span {
454458
{
455459
use serde::de;
456460

457-
if let Some(span) = v.strip_prefix("span-chars-") {
458-
if let Some((start, end)) = span.split_once('-') {
461+
if let Some((file_id, char_span)) = v.split_once(':') {
462+
let file_id = file_id
463+
.parse::<usize>()
464+
.map_err(|e| de::Error::custom(e.to_string()))?;
465+
466+
if let Some((start, end)) = char_span.split_once('-') {
459467
let start = start
460468
.parse::<usize>()
461469
.map_err(|e| de::Error::custom(e.to_string()))?;
462470
let end = end
463471
.parse::<usize>()
464472
.map_err(|e| de::Error::custom(e.to_string()))?;
465473

466-
return Ok(Span { start, end });
474+
return Ok(Span {
475+
start,
476+
end,
477+
source_id: file_id,
478+
});
467479
}
468480
}
481+
469482
Err(de::Error::custom("malformed span"))
470483
}
471484

0 commit comments

Comments
 (0)