Skip to content

Commit

Permalink
add primitive values support and more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
faultyserver committed Dec 20, 2023
1 parent b50b85a commit 23db478
Show file tree
Hide file tree
Showing 28 changed files with 717 additions and 34 deletions.
49 changes: 46 additions & 3 deletions crates/biome_css_formatter/src/css/auxiliary/identifier.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
use std::borrow::Cow;

use crate::prelude::*;
use biome_css_syntax::{CssIdentifier, CssIdentifierFields};
use biome_formatter::write;
use biome_formatter::{token::string::ToAsciiLowercaseCow, write, FormatRuleWithOptions};

#[derive(Default, Debug)]
pub(crate) struct FormatCssIdentifierOptions {
/// Whether the formatter should rewrite the identifier using lowercase
/// letters.
pub(crate) forced_lowercase: bool,
}

impl FormatRuleWithOptions<CssIdentifier> for FormatCssIdentifier {
type Options = FormatCssIdentifierOptions;

fn with_options(mut self, options: Self::Options) -> Self {
self.forced_lowercase = options.forced_lowercase;
self
}
}

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssIdentifier;
pub(crate) struct FormatCssIdentifier {
forced_lowercase: bool,
}

impl FormatNodeRule<CssIdentifier> for FormatCssIdentifier {
fn fmt_fields(&self, node: &CssIdentifier, f: &mut CssFormatter) -> FormatResult<()> {
let CssIdentifierFields { value_token } = node.as_fields();

write!(f, [value_token.format()])
// The parser uses identifiers to represent a few different things:
// selector names, rule names, values, and also units. For formatting,
// we always want to write units in lowercase, but all of the others
// we want to preserve their casing.
if self.forced_lowercase {
let value_token = value_token?;

let original = value_token.text_trimmed();
match original.to_ascii_lowercase_cow() {
Cow::Borrowed(_) => write![f, [value_token.format()]],
Cow::Owned(lowercase) => {
write!(
f,
[format_replaced(
&value_token,
&dynamic_text(&lowercase, value_token.text_trimmed_range().start())
)]
)
}
}
} else {
write!(f, [value_token.format()])
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ pub(crate) struct FormatCssCompoundSelectorList;
impl FormatRule<CssCompoundSelectorList> for FormatCssCompoundSelectorList {
type Context = CssFormatContext;
fn fmt(&self, node: &CssCompoundSelectorList, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
f.join().entries(node.iter().formatted()).finish()
}
}
6 changes: 4 additions & 2 deletions crates/biome_css_formatter/src/css/lists/selector_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ impl FormatRule<CssSelectorList> for FormatCssSelectorList {
// Each selector gets `indent` added in case it breaks over multiple
// lines. The break is added here rather than in each selector both
// for simplicity and to avoid recursively adding indents when
// selectors are nested within other rules.
// selectors are nested within other rules. The group is then added
// around the indent to ensure that it tries using a flat layout
// first and only expands when the single selector can't fit the line.
//
// For example, a selector like `div span a` is structured like
// `[div, [span, [a]]]`, so `a` would end up double-indented if it
// was handled by the selector rather than here.
joiner.entry(rule.node()?.syntax(), &indent(&formatted));
joiner.entry(rule.node()?.syntax(), &group(&indent(&formatted)));
}

joiner.finish()
Expand Down
9 changes: 6 additions & 3 deletions crates/biome_css_formatter/src/css/value/number.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::prelude::*;
use biome_css_syntax::CssNumber;
use biome_rowan::AstNode;
use biome_css_syntax::{CssNumber, CssNumberFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssNumber;
impl FormatNodeRule<CssNumber> for FormatCssNumber {
fn fmt_fields(&self, node: &CssNumber, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssNumberFields { value_token } = node.as_fields();

write!(f, [value_token.format()])
}
}
9 changes: 6 additions & 3 deletions crates/biome_css_formatter/src/css/value/percent_dimension.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::prelude::*;
use biome_css_syntax::CssPercentDimension;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPercentDimension, CssPercentDimensionFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPercentDimension;
impl FormatNodeRule<CssPercentDimension> for FormatCssPercentDimension {
fn fmt_fields(&self, node: &CssPercentDimension, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPercentDimensionFields { value, unit_token } = node.as_fields();

write!(f, [value.format(), unit_token.format()])
}
}
11 changes: 8 additions & 3 deletions crates/biome_css_formatter/src/css/value/percentage.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use crate::prelude::*;
use biome_css_syntax::CssPercentage;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPercentage, CssPercentageFields};
use biome_formatter::write;
#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPercentage;
impl FormatNodeRule<CssPercentage> for FormatCssPercentage {
fn fmt_fields(&self, node: &CssPercentage, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPercentageFields {
value,
reminder_token,
} = node.as_fields();

write!(f, [value.format(), reminder_token.format()])
}
}
22 changes: 19 additions & 3 deletions crates/biome_css_formatter/src/css/value/ratio.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
use crate::prelude::*;
use biome_css_syntax::CssRatio;
use biome_rowan::AstNode;
use biome_css_syntax::{CssRatio, CssRatioFields};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssRatio;
impl FormatNodeRule<CssRatio> for FormatCssRatio {
fn fmt_fields(&self, node: &CssRatio, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssRatioFields {
numerator,
slash_token,
denominator,
} = node.as_fields();

write!(
f,
[group(&format_args![
numerator.format(),
space(),
slash_token.format(),
soft_line_break_or_space(),
denominator.format()
])]
)
}
}
22 changes: 18 additions & 4 deletions crates/biome_css_formatter/src/css/value/regular_dimension.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
use crate::prelude::*;
use biome_css_syntax::CssRegularDimension;
use biome_rowan::AstNode;
use crate::{css::auxiliary::identifier::FormatCssIdentifierOptions, prelude::*};
use biome_css_syntax::{CssRegularDimension, CssRegularDimensionFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssRegularDimension;
impl FormatNodeRule<CssRegularDimension> for FormatCssRegularDimension {
fn fmt_fields(&self, node: &CssRegularDimension, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssRegularDimensionFields { value, unit } = node.as_fields();

write!(f, [value.format()])?;

if let Ok(unit) = unit {
write!(
f,
[unit.format().with_options(FormatCssIdentifierOptions {
forced_lowercase: true
})]
)?;
}

Ok(())
}
}
9 changes: 6 additions & 3 deletions crates/biome_css_formatter/src/css/value/string.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::prelude::*;
use biome_css_syntax::CssString;
use biome_rowan::AstNode;
use biome_css_syntax::{CssString, CssStringFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssString;
impl FormatNodeRule<CssString> for FormatCssString {
fn fmt_fields(&self, node: &CssString, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssStringFields { value_token } = node.as_fields();

write!(f, [value_token.format()])
}
}
8 changes: 5 additions & 3 deletions crates/biome_css_formatter/tests/quick_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ mod language {
include!("language.rs");
}

// #[ignore]
#[ignore]
#[test]
// use this test check if your snippet prints as you wish, without using a snapshot
fn quick_test() {
let src = r#"
.complex * | html {
div
span, span p {
font-size: 12px;
}
"#;
let parse = parse_css(src, CssParserOptions::default());
println!("{:#?}", parse);

let options = CssFormatOptions::default();
let doc = format_node(options.clone(), &parse.syntax()).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
.newline {
color: blue; background-color: red;
}
.no-trailing-semi {
color: blue
}

.empty-line {
color: blue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ info: css/declaration_list.css
.newline {
color: blue; background-color: red;
}
.no-trailing-semi {
color: blue
}

.empty-line {
color: blue;
Expand Down Expand Up @@ -61,6 +64,9 @@ Line width: 80
color: blue;
background-color: red;
}
.no-trailing-semi {
color: blue;
}

.empty-line {
color: blue;
Expand All @@ -80,9 +86,3 @@ Line width: 80
```



## Unimplemented nodes/tokens

" 12p" => 307..311
" 70" => 328..331

6 changes: 6 additions & 0 deletions crates/biome_css_formatter/tests/specs/css/dimensions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
p {
font-size: 100 ;
font-size: 100% ;
font-size: 10 / 5 ;
font-size: "foo" ;
}
40 changes: 40 additions & 0 deletions crates/biome_css_formatter/tests/specs/css/dimensions.css.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: css/dimensions.css
---

# Input

```css
p {
font-size: 100 ;
font-size: 100% ;
font-size: 10 / 5 ;
font-size: "foo" ;
}
```


=============================

# Outputs

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
-----

```css
p {
font-size: 100;
font-size: 100%;
font-size: 10 / 5;
font-size: "foo";
}
```


7 changes: 7 additions & 0 deletions crates/biome_css_formatter/tests/specs/css/important.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
html {
font-size: 12px!important;
font-size: 12px !important;
color: red ! important;
background-color: white !
important;
}
41 changes: 41 additions & 0 deletions crates/biome_css_formatter/tests/specs/css/important.css.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: css/important.css
---

# Input

```css
html {
font-size: 12px!important;
font-size: 12px !important;
color: red ! important;
background-color: white !
important;
}
```


=============================

# Outputs

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
-----

```css
html {
font-size: 12px !important;
font-size: 12px !important;
color: red !important;
background-color: white !important;
}
```


Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.one {}
.one.two {}

.one .two {}
.one.two .three.four {}


div.one.two {}
div#one.two {}
div.one#two {}
div .one {}
div .one.two {}

.one.two.three.four.five.six.seven.eight.nine.ten.eleven.twelve.thirteen.fourteen.fifteen.sixteen.seventeen.eighteen.nineteen.twenty {}

.one, .two {}
.one.two, .three.four {}
.one .two.three, .four {}
Loading

0 comments on commit 23db478

Please sign in to comment.