134 lines
3.4 KiB
Rust
134 lines
3.4 KiB
Rust
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// Lic// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
//
|
|
// Copyright (c) 2024, Olof Kraigher olof.kraigher@gmail.com
|
|
|
|
use crate::ast::ArchitectureBody;
|
|
use crate::formatting::buffer::Buffer;
|
|
use crate::formatting::VHDLFormatter;
|
|
use crate::{indented, HasTokenSpan, TokenSpan};
|
|
|
|
impl VHDLFormatter<'_> {
|
|
pub fn format_architecture(&self, arch: &ArchitectureBody, buffer: &mut Buffer) {
|
|
self.format_context_clause(&arch.context_clause, buffer);
|
|
if let Some(item) = arch.context_clause.last() {
|
|
self.line_break_preserve_whitespace(item.span().end_token, buffer);
|
|
}
|
|
let span = arch.span();
|
|
// architecture <ident> of <ident> is
|
|
self.format_token_span(TokenSpan::new(span.start_token, arch.is_token()), buffer);
|
|
indented!(buffer, { self.format_declarations(&arch.decl, buffer) });
|
|
buffer.line_break();
|
|
self.format_token_id(arch.begin_token, buffer);
|
|
indented!(buffer, {
|
|
self.format_concurrent_statements(&arch.statements, buffer);
|
|
});
|
|
buffer.line_break();
|
|
// end [architecture] [name];
|
|
self.format_token_span(TokenSpan::new(arch.end_token, span.end_token - 1), buffer);
|
|
self.format_token_id(span.end_token, buffer);
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use crate::syntax::test::Code;
|
|
use vhdl_lang::formatting::test_utils::check_formatted;
|
|
|
|
fn check_architecture_formatted(input: &str) {
|
|
check_formatted(
|
|
input,
|
|
input,
|
|
Code::architecture_body,
|
|
|formatter, arch, buffer| formatter.format_architecture(arch, buffer),
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn format_empty_architecture() {
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
begin
|
|
end foo;",
|
|
);
|
|
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
begin
|
|
end architecture foo;",
|
|
);
|
|
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
begin
|
|
end;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn format_architecture_with_declarations() {
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
constant x: foo := bar;
|
|
begin
|
|
end foo;",
|
|
);
|
|
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
constant x: foo := bar;
|
|
signal y: bar := foobar;
|
|
begin
|
|
end foo;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn format_full_architecture() {
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
constant x: foo := bar;
|
|
signal y: bar := foobar;
|
|
begin
|
|
bar: process(clk) is
|
|
variable z: baz;
|
|
begin
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
foo <= '0';
|
|
else
|
|
foo <= bar and baz;
|
|
end if;
|
|
end if;
|
|
end process bar;
|
|
y <= x; -- An assignment
|
|
end foo;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn format_architecture_preserve_whitespace() {
|
|
check_architecture_formatted(
|
|
"\
|
|
architecture foo of bar is
|
|
constant x: foo := bar;
|
|
constant baz: char := '1';
|
|
|
|
signal y: bar := foobar;
|
|
signal foobar: std_logic := 'Z';
|
|
|
|
shared variable sv: natural;
|
|
begin
|
|
end foo;",
|
|
);
|
|
}
|
|
}
|