Skip to content

Commit

Permalink
fix prisma/language-tools#187 : end of line comments must not interfe…
Browse files Browse the repository at this point in the history
…re with the table layout
  • Loading branch information
mavilein committed May 28, 2020
1 parent c87031c commit 2e6f31f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 11 deletions.
3 changes: 2 additions & 1 deletion libs/datamodel/core/src/ast/reformat/reformatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ impl<'a> Reformatter<'a> {
match current.as_rule() {
Rule::non_empty_identifier => target.write(current.as_str()),
Rule::directive => Self::reformat_directive(&mut target.column_locked_writer_for(2), &current, "@"),
Rule::doc_comment | Rule::comment => target.append_suffix_to_current_row(current.as_str()),
_ => Self::reformat_generic_token(target, &current),
}
}
Expand All @@ -334,7 +335,7 @@ impl<'a> Reformatter<'a> {
}
Rule::directive => Self::reformat_directive(&mut target.column_locked_writer_for(2), &current, "@"),
// This is a comment at the end of a field.
Rule::doc_comment => comment(target, current.as_str()),
Rule::doc_comment | Rule::comment => target.append_suffix_to_current_row(current.as_str()),
// This is a comment before the field declaration. Hence it must be interlevaed.
Rule::doc_comment_and_new_line => comment(&mut target.interleave_writer(), current.as_str()),
Rule::NEWLINE => {} // we do the new lines ourselves
Expand Down
35 changes: 26 additions & 9 deletions libs/datamodel/core/src/ast/renderer/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ use std::cmp::max;
const COLUMN_SPACING: usize = 1;

pub enum Row {
Regular(Vec<String>),
// the 2nd String is an arbitrary String that does not influence the table layout. We use it for end of line comments.
Regular(Vec<String>, String),
Interleaved(String),
}

impl Row {
fn new_regular() -> Row {
Row::Regular(Vec::new(), "".to_owned())
}
}

pub struct TableFormat {
pub table: Vec<Row>,
row: i32,
Expand Down Expand Up @@ -56,7 +63,7 @@ impl TableFormat {
}

let index = match &self.table[self.row as usize] {
Row::Regular(row) => row.len() - 1,
Row::Regular(row, _) => row.len() - 1,
Row::Interleaved(_) => panic!("Cannot lock col in interleaved mode"),
};

Expand Down Expand Up @@ -86,7 +93,7 @@ impl TableFormat {
}

match &mut self.table[self.row as usize] {
Row::Regular(row) => {
Row::Regular(row, _) => {
while row.len() <= index {
row.push(String::new());
}
Expand All @@ -101,8 +108,15 @@ impl TableFormat {
}
}

pub fn append_suffix_to_current_row(&mut self, text: &str) {
match &mut self.table[self.row as usize] {
Row::Regular(_, suffix) => suffix.push_str(text),
_ => panic!("State error: Not inside a regular table row."),
}
}

pub fn start_new_line(&mut self) {
self.table.push(Row::Regular(Vec::new()));
self.table.push(Row::new_regular());
self.row += 1;
}

Expand All @@ -111,15 +125,15 @@ impl TableFormat {
let mut max_number_of_columns = 0;

for row in &self.table {
if let Row::Regular(row) = row {
if let Row::Regular(row, _) = row {
max_number_of_columns = max(max_number_of_columns, row.len());
}
}

let mut max_widths_for_each_column = vec![0; max_number_of_columns];

for row in &self.table {
if let Row::Regular(row) = row {
if let Row::Regular(row, _) = row {
for (i, col) in row.iter().enumerate() {
max_widths_for_each_column[i] = max(max_widths_for_each_column[i], col.len());
}
Expand All @@ -129,7 +143,7 @@ impl TableFormat {
// Then, render
for row in &self.table {
match row {
Row::Regular(row) => {
Row::Regular(row, suffix) => {
for (i, col) in row.iter().enumerate() {
let spacing = if i == row.len() - 1 {
0 // Do not space last column.
Expand All @@ -138,6 +152,9 @@ impl TableFormat {
};
target.write(&format!("{}{}", col, " ".repeat(spacing)));
}
if !suffix.is_empty() {
target.write(&format!(" {}", suffix));
}
}
Row::Interleaved(text) => {
target.write(text);
Expand All @@ -162,7 +179,7 @@ impl LineWriteable for TableFormat {
let trimmed = text.trim();

match &mut self.table[self.row as usize] {
Row::Regular(row) => row.push(String::from(trimmed)),
Row::Regular(row, _) => row.push(String::from(trimmed)),
_ => panic!("State error: Not inside a regular table row."),
}
}
Expand Down Expand Up @@ -233,7 +250,7 @@ impl<'a> LineWriteable for ColumnLockedWriter<'a> {
true
} else {
match &self.formatter.table.last().unwrap() {
Row::Regular(row) => row.len() <= self.column || row[self.column].is_empty(),
Row::Regular(row, _) => row.len() <= self.column || row[self.column].is_empty(),
Row::Interleaved(s) => s.is_empty(),
}
}
Expand Down
38 changes: 37 additions & 1 deletion libs/datamodel/core/tests/reformat/reformat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn test_reformat_model_complex() {

let expected = r#"/// model doc comment
model User {
id Int @id // doc comment on the side
id Int @id // doc comment on the side
fieldA String @unique // comment on the side
// comment before
/// doc comment before
Expand Down Expand Up @@ -96,6 +96,42 @@ fn comments_in_a_model_must_not_move() {
assert_reformat(input, expected);
}

#[test]
fn end_of_line_comments_must_not_influence_table_layout_in_models() {
let input = r#"model Test {
id Int @id // Comment 1
foo String // Comment 2
bar bar? @relation(fields: [id], references: [id]) // Comment 3
}
"#;

let expected = r#"model Test {
id Int @id // Comment 1
foo String // Comment 2
bar bar? @relation(fields: [id], references: [id]) // Comment 3
}
"#;

assert_reformat(input, expected);
}

#[test]
fn end_of_line_comments_must_not_influence_table_layout_in_enums() {
let input = r#"enum Foo {
ONE @map("short") // COMMENT 1
TWO @map("a_very_long_name") // COMMENT 2
}
"#;

let expected = r#"enum Foo {
ONE @map("short") // COMMENT 1
TWO @map("a_very_long_name") // COMMENT 2
}
"#;

assert_reformat(input, expected);
}

#[test]
fn commented_models_dont_get_removed() {
let input = r#"
Expand Down

0 comments on commit 2e6f31f

Please sign in to comment.