Skip to content

Commit

Permalink
Parse candidates in .svelte files with class:abc="condition" synt…
Browse files Browse the repository at this point in the history
…ax (#13274)

* handle `.svelte` file

In svelte there is a convention where you can use `<div
class:px-4="condition" />` which means that we extract `class:px-4` as a
utility where `class` is a variant.

This is obviously incorrect, to solve this we can ignore the `class:`
part before parsing the whole file.

This is also what we do in v3.

Ideally we have completely separate parsers for various programming
languages (based on file type) and fallback to the generic one we have
now.

Implementing that, is a much bigger scope.

* flatten match arms

* add test to verify we can parse `class:px-4="condition"`

* explicitly ingore everything but the svelte file

* merge tests

There is some funky stuff happening when running `cargo test` where it
sees contents from another test. Maybe a bug in the tmpdir crate.

I don't see this problem locally when running `cargo nextest run`, but
when using the native `cargo test` command it fails.

* update changelog

* run prettier

* Update oxide/crates/core/src/lib.rs

Co-authored-by: Jordan Pittman <[email protected]>

* fixup syntax errors

---------

Co-authored-by: Jordan Pittman <[email protected]>
  • Loading branch information
RobinMalfait and thecrypticace authored Mar 18, 2024
1 parent cdb0997 commit f3e7880
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Validate bare values ([#13245](https://github.com/tailwindlabs/tailwindcss/pull/13245))
- Parse candidates in `.svelte` files with `class:abc="condition"` syntax ([#13274](https://github.com/tailwindlabs/tailwindcss/pull/13274))

### Changed

Expand Down
45 changes: 29 additions & 16 deletions oxide/crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::parser::Extractor;
use bstr::ByteSlice;
use cache::Cache;
use fxhash::FxHashSet;
use ignore::DirEntry;
Expand Down Expand Up @@ -399,6 +400,32 @@ pub fn scan_files(input: Vec<ChangedContent>, options: u8) -> Vec<String> {
}
}

fn read_changed_content(c: ChangedContent) -> Option<Vec<u8>> {
if let Some(content) = c.content {
return Some(content.into_bytes());
}

let Some(file) = c.file else {
return Default::default();
};

let Ok(content) = std::fs::read(&file).map_err(|e| {
event!(tracing::Level::ERROR, "Failed to read file: {:?}", e);
e
}) else {
return Default::default();
};

let Some(extension) = file.extension().map(|x| x.to_str()) else {
return Some(content);
};

match extension {
Some("svelte") => Some(content.replace(" class:", " ")),
_ => Some(content),
}
}

#[tracing::instrument(skip(changed_content))]
fn read_all_files(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {
event!(
Expand All @@ -409,17 +436,7 @@ fn read_all_files(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {

changed_content
.into_par_iter()
.map(|c| match (c.file, c.content) {
(Some(file), None) => match std::fs::read(file) {
Ok(content) => content,
Err(e) => {
event!(tracing::Level::ERROR, "Failed to read file: {:?}", e);
Default::default()
}
},
(None, Some(content)) => content.into_bytes(),
_ => Default::default(),
})
.filter_map(read_changed_content)
.collect()
}

Expand All @@ -433,11 +450,7 @@ fn read_all_files_sync(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {

changed_content
.into_iter()
.filter_map(|c| match (c.file, c.content) {
(Some(file), None) => std::fs::read(file).ok(),
(None, Some(content)) => Some(content.into_bytes()),
_ => Default::default(),
})
.filter_map(read_changed_content)
.collect()
}

Expand Down
7 changes: 6 additions & 1 deletion oxide/crates/core/tests/auto_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,14 @@ mod auto_content {
("foo.jpg", Some("xl:font-bold")),
// A file that is ignored
("foo.html", Some("lg:font-bold")),
// A svelte file with `class:foo="bar"` syntax
("index.svelte", Some("<div class:px-4='condition'></div>")),
])
.1;

assert_eq!(candidates, vec!["font-bold", "md:flex"]);
assert_eq!(
candidates,
vec!["condition", "div", "font-bold", "md:flex", "px-4"]
);
}
}

0 comments on commit f3e7880

Please sign in to comment.