1use crate::{
2 comments::write_comments,
3 formatter::*,
4 utils::map::byte_span::{self, ByteSpan, LeafSpans},
5};
6use std::fmt::Write;
7use sway_ast::{
8 keywords::{
9 ContractToken, Keyword, LibraryToken, PredicateToken, ScriptToken, SemicolonToken, Token,
10 },
11 Item, ItemKind, Module, ModuleKind,
12};
13use sway_types::Spanned;
14
15pub(crate) mod item;
16pub(crate) mod submodule;
17
18impl Format for Module {
19 fn format(
20 &self,
21 formatted_code: &mut FormattedCode,
22 formatter: &mut Formatter,
23 ) -> Result<(), FormatterError> {
24 write_comments(formatted_code, 0..self.span().start(), formatter)?;
25 self.kind.format(formatted_code, formatter)?;
26 writeln!(formatted_code, "{}", SemicolonToken::AS_STR)?;
27
28 if !self.items.is_empty() {
30 write_comments(
31 formatted_code,
32 0..self.items.first().unwrap().span().start(),
33 formatter,
34 )?;
35 }
36
37 let iter = self.items.iter();
38 let mut prev_item: Option<&Item> = None;
39 for item in iter.clone() {
40 if let Some(prev_item) = prev_item {
41 write_comments(
42 formatted_code,
43 prev_item.span().end()..item.span().start(),
44 formatter,
45 )?;
46 }
47
48 item.format(formatted_code, formatter)?;
49 if let ItemKind::Submodule { .. } = item.value {
50 } else {
52 writeln!(formatted_code)?;
53 }
54
55 prev_item = Some(item);
56 }
57
58 if let Some(prev_item) = prev_item {
59 write_comments(
60 formatted_code,
61 prev_item.span().end()..self.span().end(),
62 formatter,
63 )?;
64 }
65
66 Ok(())
67 }
68}
69
70impl Format for ModuleKind {
71 fn format(
72 &self,
73 formatted_code: &mut FormattedCode,
74 _formatter: &mut Formatter,
75 ) -> Result<(), FormatterError> {
76 match self {
77 ModuleKind::Script { script_token: _ } => {
78 write!(formatted_code, "{}", ScriptToken::AS_STR)?
79 }
80 ModuleKind::Contract { contract_token: _ } => {
81 write!(formatted_code, "{}", ContractToken::AS_STR)?
82 }
83 ModuleKind::Predicate { predicate_token: _ } => {
84 write!(formatted_code, "{}", PredicateToken::AS_STR)?
85 }
86 ModuleKind::Library { library_token: _ } => {
87 write!(formatted_code, "{}", LibraryToken::AS_STR)?;
88 }
89 };
90
91 Ok(())
92 }
93}
94
95impl LeafSpans for Module {
96 fn leaf_spans(&self) -> Vec<ByteSpan> {
97 let mut collected_spans = vec![byte_span::STARTING_BYTE_SPAN];
98 collected_spans.append(&mut self.kind.leaf_spans());
99 collected_spans.push(ByteSpan::from(self.semicolon_token.span()));
100 collected_spans.append(&mut self.items.leaf_spans());
101 collected_spans
102 }
103}
104
105impl LeafSpans for ModuleKind {
106 fn leaf_spans(&self) -> Vec<ByteSpan> {
107 match self {
108 ModuleKind::Script { script_token } => {
109 vec![ByteSpan::from(script_token.span())]
110 }
111 ModuleKind::Contract { contract_token } => {
112 vec![ByteSpan::from(contract_token.span())]
113 }
114 ModuleKind::Predicate { predicate_token } => {
115 vec![ByteSpan::from(predicate_token.span())]
116 }
117 ModuleKind::Library { library_token } => {
118 vec![ByteSpan::from(library_token.span())]
119 }
120 }
121 }
122}