Skip to content

Commit 5932033

Browse files
authored
Merge pull request #456 from Kmeakin/surface-byterange
Use `ByteRange` instead of `FileRange` in surface AST
2 parents 597bd3f + 9cf5aa5 commit 5932033

File tree

9 files changed

+461
-340
lines changed

9 files changed

+461
-340
lines changed

fathom/src/core/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//! use codespan_reporting::term::termcolor::{BufferedStandardStream, ColorChoice};
1212
//! use fathom::core::pretty::Context;
1313
//! use fathom::core::Module;
14+
//! use fathom::files::FileId;
1415
//! use fathom::source::StringInterner;
1516
//!
1617
//! // These are created for demonstration

fathom/src/driver.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use codespan_reporting::term::termcolor::{BufferedStandardStream, ColorChoice, W
99
use crate::core::binary::{self, BufferError, ReadError};
1010
use crate::files::{FileId, Files};
1111
use crate::source::{ByteRange, Span, StringInterner};
12+
use crate::surface::elaboration::ItemEnv;
1213
use crate::surface::{self, elaboration};
1314
use crate::{core, BUG_REPORT_URL};
1415

@@ -192,7 +193,8 @@ impl<'surface, 'core> Driver<'surface, 'core> {
192193
}
193194

194195
pub fn elaborate_and_emit_module(&mut self, file_id: FileId, pretty_core: bool) -> Status {
195-
let mut context = elaboration::Context::new(&self.interner, &self.core_scope);
196+
let mut context =
197+
elaboration::Context::new(file_id, &self.interner, &self.core_scope, ItemEnv::new());
196198

197199
let surface_module = self.parse_module(file_id);
198200
let module = context.elab_module(&self.core_scope, &surface_module, &mut |m| {
@@ -217,7 +219,8 @@ impl<'surface, 'core> Driver<'surface, 'core> {
217219
}
218220

219221
pub fn elaborate_and_emit_term(&mut self, file_id: FileId) -> Status {
220-
let mut context = elaboration::Context::new(&self.interner, &self.core_scope);
222+
let mut context =
223+
elaboration::Context::new(file_id, &self.interner, &self.core_scope, ItemEnv::new());
221224

222225
// Parse and elaborate the term
223226
let surface_term = self.parse_term(file_id);
@@ -241,7 +244,8 @@ impl<'surface, 'core> Driver<'surface, 'core> {
241244
}
242245

243246
pub fn normalise_and_emit_term(&mut self, file_id: FileId) -> Status {
244-
let mut context = elaboration::Context::new(&self.interner, &self.core_scope);
247+
let mut context =
248+
elaboration::Context::new(file_id, &self.interner, &self.core_scope, ItemEnv::new());
245249

246250
// Parse and elaborate the term
247251
let surface_term = self.parse_term(file_id);
@@ -277,22 +281,27 @@ impl<'surface, 'core> Driver<'surface, 'core> {
277281

278282
let initial_buffer = binary::Buffer::from(buffer_data);
279283
let mut binary_context = binary::Context::new(initial_buffer);
280-
let mut elab_context = elaboration::Context::new(&self.interner, &self.core_scope);
284+
let mut item_env = ItemEnv::new();
281285

282286
// Parse and elaborate a module if one was provided
283287
if let Some(file_id) = module_file_id {
288+
let mut elab_context =
289+
elaboration::Context::new(file_id, &self.interner, &self.core_scope, item_env);
284290
let surface_module = self.parse_module(file_id);
285291
let module = elab_context.elab_module(&self.core_scope, &surface_module, &mut |m| {
286292
self.emit_diagnostic(m.to_diagnostic(&self.interner));
287293
});
288294
// Add it to the binary context
289295
binary_context.add_module(&module);
296+
item_env = elab_context.finish();
290297
}
291298

292299
// Parse and elaborate the supplied format with the items from the
293300
// supplied in the module in scope. This is still a bit of a hack, and
294301
// will need to be revisited if we need to support multiple modules, but
295302
// it works for now!
303+
let mut elab_context =
304+
elaboration::Context::new(format_file_id, &self.interner, &self.core_scope, item_env);
296305
let surface_format = self.parse_term(format_file_id);
297306
let format = elab_context.elab_format(&self.core_scope, &surface_format, &mut |m| {
298307
self.emit_diagnostic(m.to_diagnostic(&self.interner));
@@ -333,17 +342,16 @@ impl<'surface, 'core> Driver<'surface, 'core> {
333342
fn parse_module(&'surface self, file_id: FileId) -> surface::Module<'surface, ByteRange> {
334343
let source = self.files.get(file_id).unwrap().source();
335344
let (module, messages) =
336-
surface::Module::parse(&self.interner, &self.surface_scope, file_id, source);
337-
self.emit_diagnostics(messages.into_iter().map(|m| m.to_diagnostic()));
345+
surface::Module::parse(&self.interner, &self.surface_scope, source);
346+
self.emit_diagnostics(messages.into_iter().map(|m| m.to_diagnostic(file_id)));
338347

339348
module
340349
}
341350

342351
fn parse_term(&'surface self, file_id: FileId) -> surface::Term<'surface, ByteRange> {
343352
let source = self.files.get(file_id).unwrap().source();
344-
let (term, messages) =
345-
surface::Term::parse(&self.interner, &self.surface_scope, file_id, source);
346-
self.emit_diagnostics(messages.into_iter().map(move |m| m.to_diagnostic()));
353+
let (term, messages) = surface::Term::parse(&self.interner, &self.surface_scope, source);
354+
self.emit_diagnostics(messages.into_iter().map(move |m| m.to_diagnostic(file_id)));
347355

348356
term
349357
}

fathom/src/files.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! A reimplementation of `codespan-reporting::files::SimpleFiles` that uses
22
//! `FileId` as the file id, instead of `usize`.
33
4+
use std::fmt;
45
use std::num::NonZeroU32;
56
use std::ops::Range;
67

@@ -13,6 +14,12 @@ use codespan_reporting::files::{Error, SimpleFile};
1314
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1415
pub struct FileId(NonZeroU32);
1516

17+
impl fmt::Display for FileId {
18+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19+
fmt::Display::fmt(&self.0, f)
20+
}
21+
}
22+
1623
impl TryFrom<u32> for FileId {
1724
type Error = <NonZeroU32 as TryFrom<u32>>::Error;
1825

fathom/src/source.rs

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Types related to source files.
22
3+
use std::fmt;
34
use std::ops::{Deref, DerefMut, Range};
45

56
use crate::files::FileId;
@@ -196,7 +197,7 @@ impl<T> DerefMut for Spanned<T> {
196197

197198
#[derive(Debug, Copy, Clone)]
198199
pub enum Span {
199-
Range(ByteRange),
200+
Range(FileRange),
200201
Empty,
201202
}
202203

@@ -209,20 +210,20 @@ impl Span {
209210
}
210211
}
211212

212-
impl From<ByteRange> for Span {
213-
fn from(range: ByteRange) -> Self {
213+
impl From<FileRange> for Span {
214+
fn from(range: FileRange) -> Self {
214215
Span::Range(range)
215216
}
216217
}
217218

218-
impl From<&ByteRange> for Span {
219-
fn from(range: &ByteRange) -> Self {
219+
impl From<&FileRange> for Span {
220+
fn from(range: &FileRange) -> Self {
220221
Span::Range(*range)
221222
}
222223
}
223224

224-
impl From<Option<ByteRange>> for Span {
225-
fn from(range: Option<ByteRange>) -> Span {
225+
impl From<Option<FileRange>> for Span {
226+
fn from(range: Option<FileRange>) -> Span {
226227
range.map_or(Span::Empty, Span::Range)
227228
}
228229
}
@@ -231,47 +232,94 @@ impl From<Option<ByteRange>> for Span {
231232
pub type BytePos = u32;
232233

233234
/// Byte ranges in source files.
234-
#[derive(Debug, Copy, Clone)]
235-
pub struct ByteRange {
235+
#[derive(Copy, Clone)]
236+
pub struct FileRange {
236237
file_id: FileId,
237-
start: BytePos,
238-
end: BytePos,
238+
byte_range: ByteRange,
239239
}
240240

241-
impl ByteRange {
242-
pub const fn new(file_id: FileId, start: BytePos, end: BytePos) -> ByteRange {
243-
ByteRange {
241+
impl fmt::Debug for FileRange {
242+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243+
write!(
244+
f,
245+
"FileRange({}, {}..{})",
246+
self.file_id, self.byte_range.start, self.byte_range.end
247+
)
248+
}
249+
}
250+
251+
impl FileRange {
252+
pub const fn new(file_id: FileId, byte_range: ByteRange) -> FileRange {
253+
FileRange {
244254
file_id,
245-
start,
246-
end,
255+
byte_range,
247256
}
248257
}
249258

250259
pub fn file_id(&self) -> FileId {
251260
self.file_id
252261
}
253262

263+
pub const fn byte_range(&self) -> ByteRange {
264+
self.byte_range
265+
}
266+
254267
pub const fn start(&self) -> BytePos {
255-
self.start
268+
self.byte_range.start
256269
}
257270

258271
pub const fn end(&self) -> BytePos {
259-
self.end
272+
self.byte_range.end
260273
}
261274

262-
pub fn merge(&self, other: &ByteRange) -> Option<ByteRange> {
275+
pub fn merge(&self, other: &FileRange) -> Option<FileRange> {
263276
if self.file_id == other.file_id {
264-
Some(ByteRange::new(
277+
Some(FileRange::new(
265278
self.file_id,
266-
self.start.min(other.start),
267-
self.end.max(other.end),
279+
ByteRange::merge(self.byte_range, other.byte_range),
268280
))
269281
} else {
270282
None
271283
}
272284
}
273285
}
274286

287+
impl From<FileRange> for Range<usize> {
288+
fn from(file_range: FileRange) -> Self {
289+
file_range.byte_range.into()
290+
}
291+
}
292+
293+
#[derive(Copy, Clone)]
294+
pub struct ByteRange {
295+
start: BytePos,
296+
end: BytePos,
297+
}
298+
299+
impl fmt::Debug for ByteRange {
300+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
301+
write!(f, "ByteRange({}..{})", self.start, self.end)
302+
}
303+
}
304+
305+
impl ByteRange {
306+
pub fn new(start: BytePos, end: BytePos) -> Self {
307+
Self { start, end }
308+
}
309+
310+
pub const fn start(&self) -> BytePos {
311+
self.start
312+
}
313+
314+
pub const fn end(&self) -> BytePos {
315+
self.end
316+
}
317+
318+
pub fn merge(self, other: Self) -> Self {
319+
Self::new(self.start.min(other.start), self.end.max(other.end))
320+
}
321+
}
322+
275323
impl From<ByteRange> for Range<usize> {
276324
fn from(range: ByteRange) -> Self {
277325
(range.start as usize)..(range.end as usize)
@@ -285,7 +333,13 @@ mod tests {
285333
#[test]
286334
/// `ByteRange` is used a lot. Ensure it doesn't grow accidentally.
287335
fn byte_range_size() {
288-
assert_eq!(std::mem::size_of::<ByteRange>(), 12);
336+
assert_eq!(std::mem::size_of::<ByteRange>(), 8);
337+
}
338+
339+
#[test]
340+
/// `FileRange` is used a lot. Ensure it doesn't grow accidentally.
341+
fn file_range_size() {
342+
assert_eq!(std::mem::size_of::<FileRange>(), 12);
289343
}
290344

291345
#[test]

0 commit comments

Comments
 (0)