feat: ensure parsing works with right indicies
This commit is contained in:
1 parent
f9d9f85924
commit
4fa909e864
4 files changed
+128
-1
No files matched your search
@@ -60,6 +60,7 @@ members = [
|
|||||||
"packages/tui",
|
"packages/tui",
|
||||||
"packages/liveview",
|
"packages/liveview",
|
||||||
"packages/rsx",
|
"packages/rsx",
|
||||||
|
"packages/autofmt",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ proc-macro2 = { version = "1.0.6" }
|
|||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.11", features = ["full", "extra-traits"] }
|
syn = { version = "1.0.11", features = ["full", "extra-traits"] }
|
||||||
dioxus-rsx = { path = "../rsx" }
|
dioxus-rsx = { path = "../rsx" }
|
||||||
|
triple_accel = "0.4.0"
|
||||||
|
serde = { version = "1.0.136", features = ["derive"] }
|
||||||
@@ -1,9 +1,74 @@
|
|||||||
//! pretty printer for rsx!
|
//! pretty printer for rsx!
|
||||||
use dioxus_rsx::*;
|
use dioxus_rsx::*;
|
||||||
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use std::fmt::{self, Write};
|
use std::{
|
||||||
|
fmt::{self, Write},
|
||||||
|
ptr::NonNull,
|
||||||
|
};
|
||||||
|
use syn::{
|
||||||
|
buffer::TokenBuffer,
|
||||||
|
parse::{ParseBuffer, ParseStream},
|
||||||
|
};
|
||||||
|
use triple_accel::{levenshtein_search, Match};
|
||||||
|
|
||||||
mod prettyplease;
|
mod prettyplease;
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, PartialEq, Hash)]
|
||||||
|
pub struct ForamttedBlock {
|
||||||
|
pub formatted: String,
|
||||||
|
pub start: usize,
|
||||||
|
pub end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: nested rsx! calls
|
||||||
|
|
||||||
|
*/
|
||||||
|
pub fn formmat_document(contents: &str) -> Vec<ForamttedBlock> {
|
||||||
|
let mut matches = levenshtein_search(b"rsx! {", contents.as_bytes()).peekable();
|
||||||
|
|
||||||
|
let mut cur_match: Option<Match> = None;
|
||||||
|
|
||||||
|
let mut formatted_blocks = Vec::new();
|
||||||
|
|
||||||
|
while let Some(item) = matches.next() {
|
||||||
|
let Match { start, end, k } = item;
|
||||||
|
|
||||||
|
match cur_match {
|
||||||
|
Some(ref this_match) => {
|
||||||
|
// abort nested matches - these get handled automatically
|
||||||
|
if start < this_match.end {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
cur_match = Some(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
cur_match = Some(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let remaining = &contents[end - 1..];
|
||||||
|
|
||||||
|
if let Some(bracket_end) = find_bracket_end(remaining) {
|
||||||
|
let sub_string = &contents[end..bracket_end + end - 1];
|
||||||
|
|
||||||
|
if let Some(new) = fmt_block(sub_string) {
|
||||||
|
if !new.is_empty() {
|
||||||
|
formatted_blocks.push(ForamttedBlock {
|
||||||
|
formatted: new,
|
||||||
|
start: end,
|
||||||
|
end: end + bracket_end - 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formatted_blocks
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fmt_block(block: &str) -> Option<String> {
|
pub fn fmt_block(block: &str) -> Option<String> {
|
||||||
let parsed: CallBody = syn::parse_str(block).ok()?;
|
let parsed: CallBody = syn::parse_str(block).ok()?;
|
||||||
|
|
||||||
@@ -175,3 +240,24 @@ pub fn write_tabs(f: &mut dyn Write, num: usize) -> std::fmt::Result {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_bracket_end(contents: &str) -> Option<usize> {
|
||||||
|
let mut depth = 0;
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
for c in contents.chars() {
|
||||||
|
if c == '{' {
|
||||||
|
depth += 1;
|
||||||
|
} else if c == '}' {
|
||||||
|
depth -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if depth == 0 {
|
||||||
|
return Some(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
@@ -93,3 +93,41 @@ fn formats_component_man_props() {
|
|||||||
|
|
||||||
print!("{formatted}");
|
print!("{formatted}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn formats_document() {
|
||||||
|
let block = r#"
|
||||||
|
rsx!{
|
||||||
|
Component {
|
||||||
|
adsasd: "asd", // this is a comment
|
||||||
|
onclick: move |_| {
|
||||||
|
let blah = 120;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let formatted = formmat_document(block);
|
||||||
|
|
||||||
|
print!("{formatted:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn formats_valid_rust_src() {
|
||||||
|
let src = r#"
|
||||||
|
//
|
||||||
|
rsx! {
|
||||||
|
div {}
|
||||||
|
div {
|
||||||
|
h3 {"asd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let formatted = formmat_document(src);
|
||||||
|
|
||||||
|
println!("{formatted:?}");
|
||||||
|
}
|
||||||
Reference in new issue
Block a user