Update tool to work with macros and reference types
This commit is contained in:
parent
22e876a0ed
commit
78c8e56e66
54
Cargo.lock
generated
54
Cargo.lock
generated
@ -13,9 +13,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.7"
|
version = "1.1.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
@ -31,9 +34,9 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.5"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -43,9 +46,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -54,9 +57,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-organizer"
|
name = "rust-organizer"
|
||||||
@ -69,21 +72,42 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter"
|
name = "shlex"
|
||||||
version = "0.22.6"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter"
|
||||||
|
version = "0.24.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9871f16d6cf5c4757dcf30d5d2172a2df6987c510c017bbb7abfb7f9aa24d06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"regex",
|
"regex",
|
||||||
|
"regex-syntax",
|
||||||
|
"streaming-iterator",
|
||||||
|
"tree-sitter-language",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter-rust"
|
name = "tree-sitter-language"
|
||||||
version = "0.21.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "277690f420bf90741dea984f3da038ace46c4fe6047cba57a66822226cde1c93"
|
checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-rust"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cffbbcb780348fbae8395742ae5b34c1fd794e4085d43aac9f259387f9a84dc8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"tree-sitter",
|
"tree-sitter-language",
|
||||||
]
|
]
|
||||||
|
@ -7,8 +7,8 @@ authors = ["Jip J. Dekker <jip@dekker.one>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
pico-args = "0.5.0"
|
pico-args = "0.5.0"
|
||||||
tree-sitter = "0.22.6"
|
tree-sitter = "0.24.3"
|
||||||
tree-sitter-rust = "0.21.2"
|
tree-sitter-rust = "0.23.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "*"
|
cc = "*"
|
||||||
|
120
src/main.rs
120
src/main.rs
@ -26,6 +26,10 @@ struct Cli {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
enum Item<'a> {
|
enum Item<'a> {
|
||||||
InnerDoc(Cow<'a, str>),
|
InnerDoc(Cow<'a, str>),
|
||||||
|
Macro {
|
||||||
|
name: &'a str,
|
||||||
|
content: Cow<'a, str>,
|
||||||
|
},
|
||||||
ModDecl {
|
ModDecl {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
content: Cow<'a, str>,
|
content: Cow<'a, str>,
|
||||||
@ -48,6 +52,7 @@ enum Item<'a> {
|
|||||||
trt: Option<&'a str>,
|
trt: Option<&'a str>,
|
||||||
content: SortableContent<'a>,
|
content: SortableContent<'a>,
|
||||||
},
|
},
|
||||||
|
MacroInvocation(Cow<'a, str>),
|
||||||
Mod {
|
Mod {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
content: SortableContent<'a>,
|
content: SortableContent<'a>,
|
||||||
@ -70,6 +75,7 @@ struct SortableContent<'a> {
|
|||||||
struct TypeIdent<'a> {
|
struct TypeIdent<'a> {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
generics: Option<&'a str>,
|
generics: Option<&'a str>,
|
||||||
|
reference_type: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> ExitCode {
|
fn main() -> ExitCode {
|
||||||
@ -100,7 +106,7 @@ impl Cli {
|
|||||||
fn run(&self) -> Result<ExitCode, String> {
|
fn run(&self) -> Result<ExitCode, String> {
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
parser
|
parser
|
||||||
.set_language(&tree_sitter_rust::language())
|
.set_language(&tree_sitter_rust::LANGUAGE.into())
|
||||||
.expect("Error loading Rust grammar");
|
.expect("Error loading Rust grammar");
|
||||||
|
|
||||||
let text = std::fs::read_to_string(&self.path)
|
let text = std::fs::read_to_string(&self.path)
|
||||||
@ -172,16 +178,36 @@ impl TryFrom<Arguments> for Cli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Item<'a> {
|
impl<'a> Item<'a> {
|
||||||
|
fn append_content(&mut self, text: &str) {
|
||||||
|
match self {
|
||||||
|
Item::Macro { content, .. }
|
||||||
|
| Item::ModDecl { content, .. }
|
||||||
|
| Item::Const { content, .. }
|
||||||
|
| Item::Type { content, .. }
|
||||||
|
| Item::Func { content, .. }
|
||||||
|
| Item::InnerDoc(content)
|
||||||
|
| Item::Use(content)
|
||||||
|
| Item::MacroInvocation(content) => {
|
||||||
|
*content = Cow::Owned(format!("{}{}", content, text));
|
||||||
|
}
|
||||||
|
Item::Impl { .. } | Item::Mod { .. } => {
|
||||||
|
// Cannot add content to these items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn item_order(&self) -> u8 {
|
fn item_order(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
Item::InnerDoc(_) => 0,
|
Item::InnerDoc(_) => 0,
|
||||||
Item::ModDecl { .. } => 1,
|
Item::Macro { .. } => 1,
|
||||||
Item::Use(_) => 2,
|
Item::ModDecl { .. } => 2,
|
||||||
Item::Const { .. } => 3,
|
Item::Use(_) => 3,
|
||||||
Item::Type { .. } => 4,
|
Item::Const { .. } => 4,
|
||||||
Item::Func { .. } => 5,
|
Item::Type { .. } => 5,
|
||||||
Item::Impl { .. } => 6,
|
Item::Func { .. } => 6,
|
||||||
Item::Mod { .. } => 7,
|
Item::Impl { .. } => 7,
|
||||||
|
Item::MacroInvocation(_) => 8,
|
||||||
|
Item::Mod { .. } => 9,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +237,7 @@ impl<'a> Item<'a> {
|
|||||||
let name = get_field_str("name").unwrap();
|
let name = get_field_str("name").unwrap();
|
||||||
Some(Self::Const { name, content })
|
Some(Self::Const { name, content })
|
||||||
}
|
}
|
||||||
"enum_item" | "struct_item" => {
|
"enum_item" | "struct_item" | "trait_item" | "type_item" => {
|
||||||
let name = get_field_str("name").unwrap();
|
let name = get_field_str("name").unwrap();
|
||||||
Some(Self::Type { name, content })
|
Some(Self::Type { name, content })
|
||||||
}
|
}
|
||||||
@ -225,6 +251,11 @@ impl<'a> Item<'a> {
|
|||||||
let content = SortableContent::within_node(text, node, Some(start), "body");
|
let content = SortableContent::within_node(text, node, Some(start), "body");
|
||||||
Some(Self::Impl { name, trt, content })
|
Some(Self::Impl { name, trt, content })
|
||||||
}
|
}
|
||||||
|
"macro_definition" => {
|
||||||
|
let name = get_field_str("name").unwrap();
|
||||||
|
Some(Self::Macro { name, content })
|
||||||
|
}
|
||||||
|
"macro_invocation" => Some(Self::MacroInvocation(content)),
|
||||||
"mod_item" => {
|
"mod_item" => {
|
||||||
let name = get_field_str("name").unwrap();
|
let name = get_field_str("name").unwrap();
|
||||||
if node.child_by_field_name("body").is_some() {
|
if node.child_by_field_name("body").is_some() {
|
||||||
@ -235,7 +266,11 @@ impl<'a> Item<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"use_declaration" => Some(Self::Use(content)),
|
"use_declaration" => Some(Self::Use(content)),
|
||||||
_ => panic!("unexpected node kind: {}", node.kind()),
|
_ => panic!(
|
||||||
|
"unexpected node kind: {}\ncontent: {}",
|
||||||
|
node.kind(),
|
||||||
|
content
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,6 +279,8 @@ impl Display for Item<'_> {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Item::InnerDoc(content)
|
Item::InnerDoc(content)
|
||||||
|
| Item::Macro { content, .. }
|
||||||
|
| Item::MacroInvocation(content)
|
||||||
| Item::ModDecl { content, .. }
|
| Item::ModDecl { content, .. }
|
||||||
| Item::Use(content)
|
| Item::Use(content)
|
||||||
| Item::Const { content, .. }
|
| Item::Const { content, .. }
|
||||||
@ -266,10 +303,14 @@ impl Ord for Item<'_> {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Item::InnerDoc(_), Item::InnerDoc(_)) => Ordering::Equal,
|
(Item::InnerDoc(_), Item::InnerDoc(_)) => Ordering::Equal,
|
||||||
(Item::Const { name: a, .. }, Item::Const { name: b, .. })
|
(Item::Const { name: a, .. }, Item::Const { name: b, .. })
|
||||||
|
| (Item::Macro { name: a, .. }, Item::Macro { name: b, .. })
|
||||||
| (Item::Mod { name: a, .. }, Item::Mod { name: b, .. })
|
| (Item::Mod { name: a, .. }, Item::Mod { name: b, .. })
|
||||||
|
| (Item::ModDecl { name: a, .. }, Item::ModDecl { name: b, .. })
|
||||||
| (Item::Type { name: a, .. }, Item::Type { name: b, .. })
|
| (Item::Type { name: a, .. }, Item::Type { name: b, .. })
|
||||||
| (Item::Func { name: a, .. }, Item::Func { name: b, .. }) => a.cmp(b),
|
| (Item::Func { name: a, .. }, Item::Func { name: b, .. }) => a.cmp(b),
|
||||||
(Item::Use(_), Item::Use(_)) => Ordering::Equal,
|
(Item::Use(_), Item::Use(_)) | (Item::MacroInvocation(_), Item::MacroInvocation(_)) => {
|
||||||
|
Ordering::Equal
|
||||||
|
}
|
||||||
(
|
(
|
||||||
Item::Impl {
|
Item::Impl {
|
||||||
name: a, trt: t_a, ..
|
name: a, trt: t_a, ..
|
||||||
@ -282,7 +323,9 @@ impl Ord for Item<'_> {
|
|||||||
if name_order == Ordering::Equal {
|
if name_order == Ordering::Equal {
|
||||||
let trt_order = t_a.unwrap_or("").cmp(t_b.unwrap_or(""));
|
let trt_order = t_a.unwrap_or("").cmp(t_b.unwrap_or(""));
|
||||||
if trt_order == Ordering::Equal {
|
if trt_order == Ordering::Equal {
|
||||||
a.generics.unwrap_or("").cmp(&b.generics.unwrap_or(""))
|
let a_parts = (a.generics.unwrap_or(""), a.reference_type.unwrap_or(""));
|
||||||
|
let b_parts = (b.generics.unwrap_or(""), b.reference_type.unwrap_or(""));
|
||||||
|
a_parts.cmp(&b_parts)
|
||||||
} else {
|
} else {
|
||||||
trt_order
|
trt_order
|
||||||
}
|
}
|
||||||
@ -290,7 +333,10 @@ impl Ord for Item<'_> {
|
|||||||
name_order
|
name_order
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => {
|
||||||
|
// eprintln!("{} -- {}", self, other);
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +353,7 @@ impl<'a> Module<'a> {
|
|||||||
let mut cursor = root.walk();
|
let mut cursor = root.walk();
|
||||||
cursor.goto_first_child();
|
cursor.goto_first_child();
|
||||||
|
|
||||||
let mut items = Vec::new();
|
let mut items: Vec<(bool, Item)> = Vec::new();
|
||||||
let mut start = None;
|
let mut start = None;
|
||||||
let mut last = None;
|
let mut last = None;
|
||||||
if cursor.node().kind() == "{" {
|
if cursor.node().kind() == "{" {
|
||||||
@ -315,11 +361,26 @@ impl<'a> Module<'a> {
|
|||||||
cursor.goto_next_sibling();
|
cursor.goto_next_sibling();
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
|
if cursor.node().kind() == "}" {
|
||||||
|
assert!(!cursor.goto_next_sibling());
|
||||||
|
break;
|
||||||
|
}
|
||||||
let node = cursor.node();
|
let node = cursor.node();
|
||||||
// println!("{} : {}\n\n", node.kind(), node.to_sexp());
|
// eprintln!("{} : {}\n\n", node.kind(), node.to_sexp());
|
||||||
if let Some(item) = Item::maybe_item(&text, node, start) {
|
let inbetween =
|
||||||
let inbetween =
|
&text[last.unwrap_or(root.start_byte())..start.unwrap_or(node.start_byte())];
|
||||||
&text[last.unwrap_or(root.start_byte())..start.unwrap_or(node.start_byte())];
|
if node.kind() == "empty_statement" {
|
||||||
|
if let Some((_, it)) = items.last_mut() {
|
||||||
|
it.append_content(";");
|
||||||
|
}
|
||||||
|
debug_assert!(
|
||||||
|
inbetween.trim().is_empty(),
|
||||||
|
"unexpected skipped content: {:?}",
|
||||||
|
inbetween
|
||||||
|
);
|
||||||
|
start = None;
|
||||||
|
last = Some(node.end_byte());
|
||||||
|
} else if let Some(item) = Item::maybe_item(&text, node, start) {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
inbetween.trim().is_empty(),
|
inbetween.trim().is_empty(),
|
||||||
"unexpected skipped content: {:?}",
|
"unexpected skipped content: {:?}",
|
||||||
@ -335,10 +396,6 @@ impl<'a> Module<'a> {
|
|||||||
if !cursor.goto_next_sibling() {
|
if !cursor.goto_next_sibling() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if cursor.node().kind() == "}" {
|
|
||||||
assert!(!cursor.goto_next_sibling());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { items }
|
Self { items }
|
||||||
@ -356,7 +413,8 @@ impl<'a> Module<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for window in self.items.windows(2) {
|
for window in self.items.windows(2) {
|
||||||
if window[0] > window[1] {
|
if window[0].1 > window[1].1 {
|
||||||
|
// eprintln!("{:?} {:?}", window[0].1, window[1].1);
|
||||||
if print_diff {
|
if print_diff {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Expected \n\"\"\"\n{}\n\"\"\"\n before \n\"\"\"\n{}\n\"\"\"",
|
"Expected \n\"\"\"\n{}\n\"\"\"\n before \n\"\"\"\n{}\n\"\"\"",
|
||||||
@ -448,12 +506,26 @@ impl<'a> TypeIdent<'a> {
|
|||||||
"type_identifier" => Self {
|
"type_identifier" => Self {
|
||||||
name: node.utf8_text(text.as_bytes()).unwrap(),
|
name: node.utf8_text(text.as_bytes()).unwrap(),
|
||||||
generics: None,
|
generics: None,
|
||||||
|
reference_type: None,
|
||||||
},
|
},
|
||||||
"generic_type" => {
|
"generic_type" => {
|
||||||
let name = get_field_str("type").unwrap();
|
let name = get_field_str("type").unwrap();
|
||||||
let generics = get_field_str("type_arguments");
|
let generics = get_field_str("type_arguments");
|
||||||
debug_assert!(generics.is_some());
|
debug_assert!(generics.is_some());
|
||||||
Self { name, generics }
|
Self {
|
||||||
|
name,
|
||||||
|
generics,
|
||||||
|
reference_type: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"reference_type" => {
|
||||||
|
let inner = node.child_by_field_name("type").unwrap();
|
||||||
|
let mut ty = TypeIdent::from_node(text, inner);
|
||||||
|
let reference_str =
|
||||||
|
std::str::from_utf8(&text.as_bytes()[node.start_byte()..inner.start_byte()])
|
||||||
|
.unwrap();
|
||||||
|
ty.reference_type = Some(reference_str);
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
_ => panic!("invalid type identifier node: {}", node.kind()),
|
_ => panic!("invalid type identifier node: {}", node.kind()),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user