Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

move formatter to its own crate

author
Giacomo Cavalieri
committer
Louis Pilfold
date (Jun 16, 2026, 3:28 PM +0100) commit f291b48e parent d702b77f change-id uposuqsk
+86 -82
+15
Cargo.lock
··· 1172 1172 "futures", 1173 1173 "gen-lsp-types", 1174 1174 "gleam-core", 1175 + "gleam-format", 1175 1176 "gleam-language-server", 1176 1177 "hexpm", 1177 1178 "hostname", ··· 1264 1265 ] 1265 1266 1266 1267 [[package]] 1268 + name = "gleam-format" 1269 + version = "1.17.0" 1270 + dependencies = [ 1271 + "camino", 1272 + "ecow", 1273 + "gleam-core", 1274 + "itertools", 1275 + "pretty-arena", 1276 + "pretty_assertions", 1277 + "vec1", 1278 + ] 1279 + 1280 + [[package]] 1267 1281 name = "gleam-language-server" 1268 1282 version = "1.17.0" 1269 1283 dependencies = [ ··· 1272 1286 "ecow", 1273 1287 "gen-lsp-types", 1274 1288 "gleam-core", 1289 + "gleam-format", 1275 1290 "hexpm", 1276 1291 "im", 1277 1292 "insta",
+1
Cargo.toml
··· 16 16 "test-project-compiler", 17 17 "hexpm", 18 18 "pretty-arena", 19 + "format", 19 20 ] 20 21 21 22 # common dependencies
+2
compiler-cli/Cargo.toml
··· 11 11 [dependencies] 12 12 # The pure compiler 13 13 gleam-core = { path = "../compiler-core" } 14 + # The gleam formatter 15 + gleam-format = { path = "../format" } 14 16 # The language server 15 17 gleam-language-server = { path = "../language-server" } 16 18 # OS SIGINT and SIGTERM signal handling
+2 -2
compiler-cli/src/format.rs
··· 21 21 fn process_stdin(check: bool) -> Result<()> { 22 22 let src = read_stdin()?.into(); 23 23 let mut out = String::new(); 24 - gleam_core::format::pretty(&mut out, &src, Utf8Path::new("<stdin>"))?; 24 + gleam_format::pretty(&mut out, &src, Utf8Path::new("<stdin>"))?; 25 25 26 26 if !check { 27 27 print!("{out}"); ··· 96 96 fn format_file(problem_files: &mut Vec<Unformatted>, path: Utf8PathBuf) -> Result<()> { 97 97 let src = crate::fs::read(&path)?.into(); 98 98 let mut output = String::new(); 99 - gleam_core::format::pretty(&mut output, &src, &path)?; 99 + gleam_format::pretty(&mut output, &src, &path)?; 100 100 101 101 if src != output { 102 102 problem_files.push(Unformatted {
-37
compiler-core/src/fix.rs
··· 1 - // SPDX-License-Identifier: Apache-2.0 2 - // SPDX-FileCopyrightText: 2023 The Gleam contributors 3 - 4 - use crate::{ 5 - Error, Result, 6 - format::{Formatter, Intermediate}, 7 - io::Utf8Writer, 8 - warning::WarningEmitter, 9 - }; 10 - use camino::Utf8Path; 11 - use ecow::EcoString; 12 - use pretty_arena::DocumentArena; 13 - 14 - pub fn parse_fix_and_format(src: &EcoString, path: &Utf8Path) -> Result<String> { 15 - // Parse 16 - let parsed = crate::parse::parse_module(path.to_owned(), src, &WarningEmitter::null()) 17 - .map_err(|error| Error::Parse { 18 - path: path.to_path_buf(), 19 - src: src.clone(), 20 - error: Box::new(error), 21 - })?; 22 - let intermediate = Intermediate::from_extra(&parsed.extra, src); 23 - let module = parsed.module; 24 - 25 - // Fix 26 - // let module = some_fixer_module::Fixer::fix(module); 27 - 28 - // Format 29 - let mut buffer = String::new(); 30 - let arena = DocumentArena::new(); 31 - Formatter::with_comments(&intermediate) 32 - .module(&arena, &module) 33 - .pretty_print(80, &mut buffer) 34 - .map_err(|error| buffer.convert_err(error))?; 35 - 36 - Ok(buffer) 37 - }
+44 -36
compiler-core/src/format.rs format/src/lib.rs
··· 4 4 #[cfg(test)] 5 5 mod tests; 6 6 7 - use crate::{ 7 + use camino::Utf8Path; 8 + use ecow::{EcoString, eco_format}; 9 + use gleam_core::{ 8 10 Error, Result, 9 11 ast::{ 10 12 CustomType, Import, ModuleConstant, TypeAlias, TypeAstConstructor, TypeAstFn, TypeAstHole, ··· 13 15 build::Target, 14 16 io::Utf8Writer, 15 17 parse::extra::{Comment, ModuleExtra}, 18 + type_::Deprecation, 16 19 warning::WarningEmitter, 17 20 }; 18 - use ecow::{EcoString, eco_format}; 19 21 use itertools::Itertools; 20 22 use pretty_arena::*; 21 23 use std::cmp::Ordering; 22 24 use vec1::Vec1; 23 25 24 - use crate::type_::Deprecation; 25 - use camino::Utf8Path; 26 - 27 26 const INDENT: isize = 2; 28 27 29 28 pub fn pretty(writer: &mut impl Utf8Writer, src: &EcoString, path: &Utf8Path) -> Result<()> { 30 - let parsed = crate::parse::parse_module(path.to_owned(), src, &WarningEmitter::null()) 29 + let parsed = gleam_core::parse::parse_module(path.to_owned(), src, &WarningEmitter::null()) 31 30 .map_err(|error| Error::Parse { 32 31 path: path.to_path_buf(), 33 32 src: src.clone(), ··· 406 405 arena.join(imports, LINE_DOCUMENT) 407 406 } 408 407 408 + fn unqualified_import( 409 + &self, 410 + arena: &'doc DocumentArena<'a, 'doc>, 411 + unqualified_import: &'a UnqualifiedImport, 412 + ) -> Document<'a, 'doc> { 413 + unqualified_import.name.as_ref().to_doc(arena).append( 414 + arena, 415 + match &unqualified_import.as_name { 416 + None => EMPTY_DOCUMENT, 417 + Some(s) => " as ".to_doc(arena).append(arena, s.as_str()), 418 + }, 419 + ) 420 + } 421 + 409 422 fn definition( 410 423 &mut self, 411 424 arena: &'doc DocumentArena<'a, 'doc>, ··· 431 444 let unqualified_types = unqualified_types 432 445 .iter() 433 446 .sorted_by(|a, b| a.name.cmp(&b.name)) 434 - .map(|type_| docvec![arena, TYPE_SPACE_DOCUMENT, type_]); 447 + .map(|import_| { 448 + docvec![ 449 + arena, 450 + TYPE_SPACE_DOCUMENT, 451 + self.unqualified_import(arena, import_) 452 + ] 453 + }); 435 454 let unqualified_values = unqualified_values 436 455 .iter() 437 456 .sorted_by(|a, b| a.name.cmp(&b.name)) 438 - .map(|value| value.to_doc(arena)); 457 + .map(|import_| self.unqualified_import(arena, import_)); 439 458 let unqualified = arena.join( 440 459 unqualified_types.chain(unqualified_values), 441 460 FLEX_COMMA_DOCUMENT, ··· 966 985 ) 967 986 } 968 987 988 + fn argument_names( 989 + &self, 990 + arena: &'doc DocumentArena<'a, 'doc>, 991 + argument_names: &'a ArgNames, 992 + ) -> Document<'a, 'doc> { 993 + match argument_names { 994 + ArgNames::Named { name, .. } | ArgNames::Discard { name, .. } => name.to_doc(arena), 995 + ArgNames::LabelledDiscard { label, name, .. } 996 + | ArgNames::NamedLabelled { label, name, .. } => { 997 + docvec![arena, label, " ", name] 998 + } 999 + } 1000 + } 1001 + 969 1002 fn fn_arg<A>( 970 1003 &mut self, 971 1004 arena: &'doc DocumentArena<'a, 'doc>, ··· 973 1006 ) -> Document<'a, 'doc> { 974 1007 let comments = self.pop_comments(argument.location.start); 975 1008 let doc = match &argument.annotation { 976 - None => argument.names.to_doc(arena), 977 - Some(type_) => argument 978 - .names 979 - .to_doc(arena) 1009 + None => self.argument_names(arena, &argument.names), 1010 + Some(type_) => self 1011 + .argument_names(arena, &argument.names) 980 1012 .append(arena, COLON_SPACE_DOCUMENT) 981 1013 .append(arena, self.type_ast(arena, type_)), 982 1014 } ··· 3855 3887 (init, [last]) => Some((init, last)), 3856 3888 _ => panic!("unreachable"), 3857 3889 }, 3858 - } 3859 - } 3860 - 3861 - impl<'a, 'doc> Documentable<'a, 'doc> for &'a ArgNames { 3862 - fn to_doc(self, arena: &'doc DocumentArena<'a, 'doc>) -> Document<'a, 'doc> { 3863 - match self { 3864 - ArgNames::Named { name, .. } | ArgNames::Discard { name, .. } => name.to_doc(arena), 3865 - ArgNames::LabelledDiscard { label, name, .. } 3866 - | ArgNames::NamedLabelled { label, name, .. } => { 3867 - docvec![arena, label, " ", name] 3868 - } 3869 - } 3870 - } 3871 - } 3872 - 3873 - impl<'a, 'doc> Documentable<'a, 'doc> for &'a UnqualifiedImport { 3874 - fn to_doc(self, arena: &'doc DocumentArena<'a, 'doc>) -> Document<'a, 'doc> { 3875 - self.name.as_str().to_doc(arena).append( 3876 - arena, 3877 - match &self.as_name { 3878 - None => EMPTY_DOCUMENT, 3879 - Some(s) => " as ".to_doc(arena).append(arena, s.as_str()), 3880 - }, 3881 - ) 3882 3890 } 3883 3891 } 3884 3892
+2 -4
compiler-core/src/format/tests.rs format/src/tests.rs
··· 28 28 macro_rules! assert_format { 29 29 ($src:expr $(,)?) => { 30 30 let mut writer = String::new(); 31 - $crate::format::pretty(&mut writer, &$src.into(), camino::Utf8Path::new("<stdin>")) 32 - .unwrap(); 31 + $crate::pretty(&mut writer, &$src.into(), camino::Utf8Path::new("<stdin>")).unwrap(); 33 32 assert_eq!($src, writer); 34 33 }; 35 34 } ··· 38 37 macro_rules! assert_format_rewrite { 39 38 ($src:expr, $expected:expr $(,)?) => { 40 39 let mut writer = String::new(); 41 - $crate::format::pretty(&mut writer, &$src.into(), camino::Utf8Path::new("<stdin>")) 42 - .unwrap(); 40 + $crate::pretty(&mut writer, &$src.into(), camino::Utf8Path::new("<stdin>")).unwrap(); 43 41 assert_eq!(writer, $expected); 44 42 }; 45 43 }
compiler-core/src/format/tests/asignments.rs format/src/tests/asignments.rs
compiler-core/src/format/tests/binary_operators.rs format/src/tests/binary_operators.rs
compiler-core/src/format/tests/bit_array.rs format/src/tests/bit_array.rs
compiler-core/src/format/tests/blocks.rs format/src/tests/blocks.rs
compiler-core/src/format/tests/cases.rs format/src/tests/cases.rs
compiler-core/src/format/tests/conditional_compilation.rs format/src/tests/conditional_compilation.rs
compiler-core/src/format/tests/constant.rs format/src/tests/constant.rs
compiler-core/src/format/tests/custom_type.rs format/src/tests/custom_type.rs
compiler-core/src/format/tests/echo.rs format/src/tests/echo.rs
compiler-core/src/format/tests/external_fn.rs format/src/tests/external_fn.rs
compiler-core/src/format/tests/external_types.rs format/src/tests/external_types.rs
compiler-core/src/format/tests/function.rs format/src/tests/function.rs
compiler-core/src/format/tests/guards.rs format/src/tests/guards.rs
compiler-core/src/format/tests/imports.rs format/src/tests/imports.rs
compiler-core/src/format/tests/lists.rs format/src/tests/lists.rs
compiler-core/src/format/tests/pipeline.rs format/src/tests/pipeline.rs
compiler-core/src/format/tests/record_update.rs format/src/tests/record_update.rs
compiler-core/src/format/tests/tuple.rs format/src/tests/tuple.rs
compiler-core/src/format/tests/use_.rs format/src/tests/use_.rs
-2
compiler-core/src/lib.rs
··· 74 74 pub mod encryption; 75 75 pub mod erlang; 76 76 pub mod error; 77 - pub mod fix; 78 - pub mod format; 79 77 pub mod hex; 80 78 pub mod io; 81 79 pub mod javascript;
+18
format/Cargo.toml
··· 1 + # SPDX-License-Identifier: Apache-2.0 2 + # SPDX-FileCopyrightText: 2020 The Gleam contributors 3 + 4 + [package] 5 + name = "gleam-format" 6 + version = "1.17.0" 7 + authors = ["Louis Pilfold <louis@lpil.uk>"] 8 + edition = "2024" 9 + license = "Apache-2.0" 10 + 11 + [dependencies] 12 + gleam-core = { path = "../compiler-core" } 13 + pretty-arena = { path = "../pretty-arena" } 14 + itertools.workspace = true 15 + vec1.workspace = true 16 + camino.workspace = true 17 + ecow.workspace = true 18 + pretty_assertions.workspace = true
+1
language-server/Cargo.toml
··· 10 10 11 11 [dependencies] 12 12 gleam-core = { path = "../compiler-core" } 13 + gleam-format = { path = "../format" } 13 14 14 15 camino.workspace = true 15 16 debug-ignore.workspace = true
+1 -1
language-server/src/server.rs
··· 338 338 Err(error) => return self.path_error_response(path, error), 339 339 }; 340 340 341 - if let Err(error) = gleam_core::format::pretty(&mut new_text, &src, &path) { 341 + if let Err(error) = gleam_format::pretty(&mut new_text, &src, &path) { 342 342 return self.path_error_response(path, error); 343 343 } 344 344