Skip to content

Commit e76e450

Browse files
committed
Move sourcemap content generation to the sourcemap module, document the sourcemap module
1 parent 42a2681 commit e76e450

File tree

2 files changed

+48
-22
lines changed

2 files changed

+48
-22
lines changed

compiler-core/src/codegen.rs

+8-22
Original file line numberDiff line numberDiff line change
@@ -259,31 +259,17 @@ impl<'a> JavaScript<'a> {
259259
self.typescript,
260260
&mut source_map_emitter,
261261
);
262+
262263
tracing::debug!(name = ?js_name, "Generated js module");
263264
writer.write(&path, &output?)?;
264265

265-
match source_map_emitter {
266-
SourceMapEmitter::Null => Ok(()),
267-
SourceMapEmitter::Emit(builder) => {
268-
let sourcemap_name = format!("{js_name}.mjs.map");
269-
let sourcemap_path = self.output_directory.join(sourcemap_name);
270-
tracing::debug!(path = ?sourcemap_path, name = ?js_name, "Emitting sourcemap for module");
271-
272-
// NOTE: This is a bit inefficient
273-
// * we first write to a buffer
274-
// * then construct a String based on the output
275-
// * then write to the output
276-
let sourcemap = builder.into_sourcemap();
277-
278-
let mut output = Vec::new();
279-
sourcemap
280-
.to_writer(&mut output)
281-
.expect("Failed to write sourcemap to memory.");
282-
let output =
283-
String::from_utf8(output).expect("Sourcemap did not generate valid UTF-8.");
284-
285-
writer.write(&sourcemap_path, &output)
286-
}
266+
if let Some(sourcemap_content) = source_map_emitter.maybe_emit_sourcemap_content() {
267+
let sourcemap_name = format!("{js_name}.mjs.map");
268+
let sourcemap_path = self.output_directory.join(sourcemap_name);
269+
tracing::debug!(path = ?sourcemap_path, name = ?js_name, "Emitting sourcemap for module");
270+
writer.write(&sourcemap_path, &sourcemap_content)?;
287271
}
272+
273+
Ok(())
288274
}
289275
}

compiler-core/src/sourcemap.rs

+40
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
1+
//! Sourcemap generation utils
2+
//!
3+
//! # What are sourcemaps ?
4+
//!
5+
//! Sourcemaps are a tool of web development that helps debugging when working
6+
//! with code that is generated from other code.
7+
//!
8+
//! A sourcemap is essentially a list of positions in a target file (the
9+
//! code generated by the tool - in our case JavaScript) linked to a location
10+
//! in the source code (Gleam) that is responsible for its presence.
11+
112
use sourcemap::SourceMapBuilder;
213

314
use crate::line_numbers::LineColumn;
415

16+
/// Tells whether or not the codegen should emit sourcemaps for all Gleam
17+
/// modules
518
#[derive(Debug, Clone, Copy)]
619
pub enum SourceMapSupport {
720
Emit,
821
None,
922
}
1023

24+
/// An utility that handles the emission of an associated sourcemap
25+
/// for a given Gleam module.
1126
pub enum SourceMapEmitter {
1227
Null,
1328
Emit(Box<SourceMapBuilder>),
@@ -24,6 +39,8 @@ impl std::fmt::Debug for SourceMapEmitter {
2439
}
2540

2641
impl SourceMapEmitter {
42+
/// Adds one mapping on the generated (javascript) file
43+
/// referring to the given Gleam source location
2744
pub fn add_mapping(
2845
&mut self,
2946
generated_code_line: u32,
@@ -47,6 +64,29 @@ impl SourceMapEmitter {
4764
}
4865
}
4966

67+
/// Consumes the SourceMapEmitter to get the content of the sourcemap as a
68+
/// String
69+
pub fn maybe_emit_sourcemap_content(self) -> Option<String> {
70+
match self {
71+
SourceMapEmitter::Null => None,
72+
SourceMapEmitter::Emit(builder) => {
73+
let sourcemap = builder.into_sourcemap();
74+
let mut output = Vec::new();
75+
// We first write to a vector then build a string, hoping that
76+
// the `sourcemap` crate generated a valid sourcemap. If it
77+
// did not, it is a bug that should be reported
78+
sourcemap
79+
.to_writer(&mut output)
80+
.expect("Failed to write sourcemap to memory.");
81+
let content =
82+
String::from_utf8(output).expect("Sourcemap did not generate valid UTF-8.");
83+
Some(content)
84+
}
85+
}
86+
}
87+
88+
/// Creates a null SourceMapEmitter.
89+
/// Any operation on this SourceMapEmitter will be no-ops
5090
pub fn null() -> Self {
5191
SourceMapEmitter::Null
5292
}

0 commit comments

Comments
 (0)