From e1c66d2fac03474723ebd2062a3885b3d31ca1af Mon Sep 17 00:00:00 2001 From: CjiW Date: Sun, 7 May 2023 10:02:11 +0800 Subject: [PATCH 1/3] primary & expression --- src/ast/fmt.rs | 35 +++++++++++++++++++++++++++++++++++ src/nomparser/expression.rs | 4 ++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/ast/fmt.rs b/src/ast/fmt.rs index f1ac87f76..88c4a4e7b 100644 --- a/src/ast/fmt.rs +++ b/src/ast/fmt.rs @@ -343,14 +343,31 @@ impl FmtBuilder { } } pub fn parse_primary_node(&mut self, node: &PrimaryNode) { + for com in &node.comments[0] { + com.format(self); + self.prefix(); + } node.value.format(self); + for com in &node.comments[1] { + self.prefix(); + com.format(self); + } } pub fn parse_array_element_node(&mut self, node: &ArrayElementNode) { + // arr[1] // 123 + // // 456 + // .foo(); node.arr.format(self); self.l_bracket(); node.index.format(self); self.r_bracket(); + for com in &node.comments[0] { + com.format(self); + self.add_tab(); + self.prefix(); + self.sub_tab(); + } } pub fn parse_parantheses_node(&mut self, node: &ParanthesesNode) { self.l_paren(); @@ -377,10 +394,19 @@ impl FmtBuilder { node.right.format(self); } pub fn parse_take_op_node(&mut self, node: &TakeOpNode) { + // head.id //123 + // //456 + // .foo(); node.head.format(self); for id in &node.field { self.dot(); id.format(self); + for com in &node.comments[0] { + com.format(self); + self.add_tab(); + self.prefix(); + self.sub_tab(); + } } } pub fn parse_impl_node(&mut self, node: &ImplNode) { @@ -422,6 +448,9 @@ impl FmtBuilder { self.enter(); } pub fn parse_func_call_node(&mut self, node: &FuncCallNode) { + // foo(1, 2, 3) // 456 + // // 123 + // .bar(); node.callee.format(self); if let Some(generic_params) = &node.generic_params { generic_params.format(self); @@ -439,6 +468,12 @@ impl FmtBuilder { } } self.r_paren(); + for com in &node.comments[0] { + com.format(self); + self.add_tab(); + self.prefix(); + self.sub_tab(); + } } pub fn parse_func_def_node(&mut self, node: &FuncDefNode) { let paralist = &node.paralist; diff --git a/src/nomparser/expression.rs b/src/nomparser/expression.rs index b76157e5e..c2ae39957 100644 --- a/src/nomparser/expression.rs +++ b/src/nomparser/expression.rs @@ -210,7 +210,7 @@ fn primary_exp(input: Span) -> IResult> { delspace(map_res( tuple(( many0(comment), - alt(( + del_newline_or_space!(alt(( number, bool_const, parantheses_exp, @@ -220,7 +220,7 @@ fn primary_exp(input: Span) -> IResult> { macro_call_exp, extern_identifier, string_literal, - )), + ))), many0(comment), )), |(lcoms, node, rcoms)| { From 44e3588b26fa26598e4fd4b0ee0e31a8711c115a Mon Sep 17 00:00:00 2001 From: CjiW Date: Sun, 28 May 2023 11:34:07 +0800 Subject: [PATCH 2/3] pref: use lasso --- Cargo.lock | 41 +++++++++++++++++++++++++++++++++++----- Cargo.toml | 1 + src/ast/ctx.rs | 2 +- src/ast/fmt.rs | 2 +- src/ast/node/comment.rs | 13 +++++++++++-- src/nomparser/comment.rs | 15 +++++++-------- 6 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5f01b99c..a51dd9c38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.0.1" @@ -551,7 +562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.12.3", "lock_api", "once_cell", "parking_lot_core", @@ -710,7 +721,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", ] [[package]] @@ -719,7 +739,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -838,7 +858,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -968,6 +988,16 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "lasso" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badc7a606a3096e40b886fb2f63803cacf11cd79796ae04e3f4b7e35a38cfc2" +dependencies = [ + "dashmap", + "hashbrown 0.13.2", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1266,6 +1296,7 @@ dependencies = [ "inkwell", "internal_macro", "kagari", + "lasso", "lazy_static", "linked-hash-map", "llvm-sys", @@ -1504,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64449cfef9483a475ed56ae30e2da5ee96448789fb2aa240a04beb6a055078bf" dependencies = [ "countme", - "hashbrown", + "hashbrown 0.12.3", "memoffset", "rustc-hash", "text-size", diff --git a/Cargo.toml b/Cargo.toml index e67aa8c48..378ded23e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ parking_lot = "0.12" derivative = "2.2" console = "0.15" anstyle = "1.0" +lasso = {version = "0.7", features = ["multi-threaded"]} [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "0.2" diff --git a/src/ast/ctx.rs b/src/ast/ctx.rs index 0c2630d2c..0e7d70793 100644 --- a/src/ast/ctx.rs +++ b/src/ast/ctx.rs @@ -935,7 +935,7 @@ impl<'a, 'ctx> Ctx<'a> { if let Some(docs) = docs { for doc in docs { if let NodeEnum::Comment(c) = *doc { - string.push_str(&c.comment); + string.push_str(&c.get_comment()); string.push('\n'); } } diff --git a/src/ast/fmt.rs b/src/ast/fmt.rs index 88c4a4e7b..3f0dc02f4 100644 --- a/src/ast/fmt.rs +++ b/src/ast/fmt.rs @@ -617,7 +617,7 @@ impl FmtBuilder { } else { self.token("//"); } - self.token(&node.comment); + self.token(&node.get_comment()); self.enter(); } pub fn parse_continue_node(&mut self, _node: &ContinueNode) { diff --git a/src/ast/node/comment.rs b/src/ast/node/comment.rs index 45b73c785..f7119f7aa 100644 --- a/src/ast/node/comment.rs +++ b/src/ast/node/comment.rs @@ -2,18 +2,27 @@ use super::*; use crate::ast::ctx::Ctx; use internal_macro::node; use lsp_types::SemanticTokenType; +lazy_static::lazy_static! { + pub static ref RODEO: lasso::ThreadedRodeo = lasso::ThreadedRodeo::default(); +} #[node] pub struct CommentNode { - pub comment: String, + pub comment_key: lasso::Spur, pub is_doc: bool, // use "///" (is_doc:true) } +impl CommentNode { + pub fn get_comment(&self) -> String { + RODEO.resolve(&self.comment_key).to_string() + } +} + impl PrintTrait for CommentNode { fn print(&self, tabs: usize, end: bool, mut line: Vec) { deal_line(tabs, &mut line, end); tab(tabs, line.clone(), end); - println!("CommentNode: {}", self.comment); + println!("CommentNode: {}", self.get_comment()); } } diff --git a/src/nomparser/comment.rs b/src/nomparser/comment.rs index e12a6ceeb..7d9b3b8f5 100644 --- a/src/nomparser/comment.rs +++ b/src/nomparser/comment.rs @@ -1,3 +1,4 @@ +use crate::ast::node::comment::RODEO; use crate::nomparser::Span; use crate::{ast::node::comment::CommentNode, ast::range::Range}; use internal_macro::{test_parser, test_parser_error}; @@ -22,14 +23,12 @@ pub fn comment(input: Span) -> IResult> { alt((terminated(take_until("\n"), tag("\n")), rest)), ), |(a, c): (LocatedSpan<&str, bool>, LocatedSpan<&str, bool>)| { - res_enum( - CommentNode { - comment: c.trim_end_matches('\r').to_string(), - range: Range::new(input, c.take_split(c.len()).0), - is_doc: a.contains("///"), - } - .into(), - ) + let comment_node = CommentNode { + comment_key: RODEO.get_or_intern(c.trim_end_matches('\r').to_string()), + range: Range::new(input, c.take_split(c.len()).0), + is_doc: a.contains("///"), + }; + res_enum(comment_node.into()) }, )(input) } From 3dd264d8c9f47c58f08fed17bfa885f5d16de7c4 Mon Sep 17 00:00:00 2001 From: CjiW Date: Sun, 28 May 2023 21:16:54 +0800 Subject: [PATCH 3/3] fix: return & let with comment --- src/ast/fmt.rs | 61 +++++++++++++++++++++---------------- src/ast/node/ret.rs | 3 +- src/ast/node/statement.rs | 1 + src/ast/node/types.rs | 3 +- src/nomparser/array.rs | 20 ++++++++++-- src/nomparser/expression.rs | 6 ++-- src/nomparser/statement.rs | 12 +++++--- 7 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/ast/fmt.rs b/src/ast/fmt.rs index 3f0dc02f4..c66148692 100644 --- a/src/ast/fmt.rs +++ b/src/ast/fmt.rs @@ -190,6 +190,7 @@ impl FmtBuilder { pub fn parse_struct_def_node(&mut self, node: &StructDefNode) { for c in node.pre_comments.iter() { c.format(self); + self.enter(); } self.prefix(); if let Some((modi, _)) = node.modifier { @@ -263,6 +264,11 @@ impl FmtBuilder { } pub fn parse_array_init_node(&mut self, node: &ArrayInitNode) { self.l_bracket(); + for com in &node.comments[0] { + com.format(self); + self.enter(); + self.prefix(); + } for (i, exp) in node.exps.iter().enumerate() { exp.format(self); if i != node.exps.len() - 1 { @@ -274,7 +280,6 @@ impl FmtBuilder { } pub fn parse_generic_param_node(&mut self, node: &GenericParamNode) { self.l_angle_bracket(); - for (i, generic) in node.generics.iter().enumerate() { match generic { Some(n) => n.format(self), @@ -289,6 +294,7 @@ impl FmtBuilder { pub fn parse_def_node(&mut self, node: &DefNode) { self.token("let"); self.space(); + self.parse_comments_with_tab(&node.comments[0]); node.var.format(self); if let Some(tp) = &node.tp { self.colon(); @@ -320,37 +326,53 @@ impl FmtBuilder { self.prefix(); statement.format(self); match &**statement { - NodeEnum::For(_) | NodeEnum::While(_) | NodeEnum::If(_) | NodeEnum::Comment(_) => {} + NodeEnum::For(_) + | NodeEnum::While(_) + | NodeEnum::If(_) + | NodeEnum::Comment(_) + | NodeEnum::Ret(_) => {} _ => { self.semicolon(); } } - match &**statement { - NodeEnum::Comment(_) => {} - _ => { - self.enter(); - } - } + self.enter(); + } + } + fn parse_comments_with_tab(&mut self, comments: &Vec>) { + for com in comments { + com.format(self); + self.enter(); + self.add_tab(); + self.prefix(); + self.sub_tab(); } } pub fn parse_ret_node(&mut self, node: &RetNode) { if let Some(value) = &node.value { self.token("return"); self.space(); + self.parse_comments_with_tab(&node.comments[0]); value.format(self); } else { self.token("return"); + self.parse_comments_with_tab(&node.comments[0]); + } + self.semicolon(); + for com in &node.comments[1] { + com.format(self); } } pub fn parse_primary_node(&mut self, node: &PrimaryNode) { for com in &node.comments[0] { com.format(self); + self.enter(); self.prefix(); } node.value.format(self); for com in &node.comments[1] { self.prefix(); com.format(self); + self.enter(); } } @@ -362,12 +384,7 @@ impl FmtBuilder { self.l_bracket(); node.index.format(self); self.r_bracket(); - for com in &node.comments[0] { - com.format(self); - self.add_tab(); - self.prefix(); - self.sub_tab(); - } + self.parse_comments_with_tab(&node.comments[0]); } pub fn parse_parantheses_node(&mut self, node: &ParanthesesNode) { self.l_paren(); @@ -401,12 +418,7 @@ impl FmtBuilder { for id in &node.field { self.dot(); id.format(self); - for com in &node.comments[0] { - com.format(self); - self.add_tab(); - self.prefix(); - self.sub_tab(); - } + self.parse_comments_with_tab(&node.comments[0]); } } pub fn parse_impl_node(&mut self, node: &ImplNode) { @@ -468,12 +480,7 @@ impl FmtBuilder { } } self.r_paren(); - for com in &node.comments[0] { - com.format(self); - self.add_tab(); - self.prefix(); - self.sub_tab(); - } + self.parse_comments_with_tab(&node.comments[0]); } pub fn parse_func_def_node(&mut self, node: &FuncDefNode) { let paralist = &node.paralist; @@ -481,6 +488,7 @@ impl FmtBuilder { for c in node.pre_comments.iter() { self.prefix(); c.format(self); + self.enter(); } self.prefix(); if let Some((modi, _)) = node.modifier { @@ -618,7 +626,6 @@ impl FmtBuilder { self.token("//"); } self.token(&node.get_comment()); - self.enter(); } pub fn parse_continue_node(&mut self, _node: &ContinueNode) { self.token("continue"); diff --git a/src/ast/node/ret.rs b/src/ast/node/ret.rs index 2c1ffffe4..4ec7269f7 100644 --- a/src/ast/node/ret.rs +++ b/src/ast/node/ret.rs @@ -29,10 +29,11 @@ impl Node for RetNode { builder: &'b BuilderEnum<'a, 'ctx>, ) -> NodeResult { let ret_pltype = ctx.rettp.as_ref().unwrap().clone(); + ctx.emit_comment_highlight(&self.comments[0]); if let Some(ret_node) = &mut self.value { // let (value, value_pltype, _) = ctx.emit_with_expectation(ret_node, Some(ret_pltype.clone()), ret_pltype.borrow().get_range().unwrap_or_default(), builder)?; let v = ret_node.emit(ctx, builder)?.get_value().unwrap(); - ctx.emit_comment_highlight(&self.comments[0]); + ctx.emit_comment_highlight(&self.comments[1]); let value_pltype = v.get_ty(); let mut value = ctx.try_load2var(self.range, v.get_value(), builder)?; let eqres = ctx.eq(ret_pltype.clone(), value_pltype.clone()); diff --git a/src/ast/node/statement.rs b/src/ast/node/statement.rs index 8f5519f33..d85a93e30 100644 --- a/src/ast/node/statement.rs +++ b/src/ast/node/statement.rs @@ -39,6 +39,7 @@ impl Node for DefNode { ctx: &'b mut Ctx<'a>, builder: &'b BuilderEnum<'a, 'ctx>, ) -> NodeResult { + ctx.emit_comment_highlight(&self.comments[0]); let range = self.range(); ctx.push_semantic_token(self.var.range, SemanticTokenType::VARIABLE, 0); if self.exp.is_none() && self.tp.is_none() { diff --git a/src/ast/node/types.rs b/src/ast/node/types.rs index 13e0f8a74..3ca565a29 100644 --- a/src/ast/node/types.rs +++ b/src/ast/node/types.rs @@ -711,7 +711,7 @@ impl Node for StructInitNode { } } -#[node] +#[node(comment)] pub struct ArrayInitNode { // pub tp: Box, pub exps: Vec>, @@ -737,6 +737,7 @@ impl Node for ArrayInitNode { ctx: &'b mut Ctx<'a>, builder: &'b BuilderEnum<'a, 'ctx>, ) -> NodeResult { + ctx.emit_comment_highlight(&self.comments[0]); let mut exps = Vec::new(); let mut tp0 = None; diff --git a/src/nomparser/array.rs b/src/nomparser/array.rs index 1129044a0..3360a4b50 100644 --- a/src/nomparser/array.rs +++ b/src/nomparser/array.rs @@ -27,15 +27,31 @@ pub fn array_init(input: Span) -> IResult> { map_res( tuple(( tag_token_symbol(TokenType::LBRACKET), + many0(del_newline_or_space!(comment)), separated_list0( tag_token_symbol(TokenType::COMMA), + tuple(( + many0(del_newline_or_space!(comment)), del_newline_or_space!(general_exp), + many0(del_newline_or_space!(comment)) + )), ), tag_token_symbol(TokenType::RBRACKET), )), - |((_, lb), exps, (_, rb))| { + |((_, lb), coms0, exps, (_, rb))| { let range = lb.start.to(rb.end); - res_enum(ArrayInitNode { exps, range }.into()) + let mut coms = vec![coms0]; + let mut exs = vec![]; + for (_, (comsl, exp, comsr)) in exps.iter().enumerate() { + coms.push(comsl.clone()); + exs.push(exp.clone()); + coms.push(comsr.clone()); + } + res_enum(ArrayInitNode { + exps:exs, + range, + comments: coms, + }.into()) }, )(input) } diff --git a/src/nomparser/expression.rs b/src/nomparser/expression.rs index c2ae39957..fb1b7b091 100644 --- a/src/nomparser/expression.rs +++ b/src/nomparser/expression.rs @@ -209,7 +209,7 @@ pub fn complex_exp(input: Span) -> IResult> { fn primary_exp(input: Span) -> IResult> { delspace(map_res( tuple(( - many0(comment), + many0(del_newline_or_space!(comment)), del_newline_or_space!(alt(( number, bool_const, @@ -221,7 +221,7 @@ fn primary_exp(input: Span) -> IResult> { extern_identifier, string_literal, ))), - many0(comment), + many0(del_newline_or_space!(comment)), )), |(lcoms, node, rcoms)| { let range = node.range(); @@ -247,7 +247,7 @@ fn take_exp_op(input: Span) -> IResult>)> { tag_token_symbol(TokenType::DOT), pair( opt(alt((identifier, tuple_field_identifier))), - many0(comment), + many0(del_newline_or_space!(comment)), ), ), |(idx, coms)| Ok::<_, ()>((ComplexOp::Field(idx), coms)), diff --git a/src/nomparser/statement.rs b/src/nomparser/statement.rs index 12e6fbec0..29e4b6ba5 100644 --- a/src/nomparser/statement.rs +++ b/src/nomparser/statement.rs @@ -102,11 +102,12 @@ pub fn new_variable(input: Span) -> IResult> { delspace(map_res( tuple(( tag_token_word(TokenType::LET), + many0(del_newline_or_space!(comment)), identifier, opt(pair(tag_token_symbol(TokenType::COLON), type_name)), opt(pair(tag_token_symbol(TokenType::ASSIGN), general_exp)), )), - |((_, start), a, tp, v)| { + |((_, start), coms0, a, tp, v)| { let mut end = a.range.end; if tp.is_some() { end = tp.as_ref().unwrap().1.range().end; @@ -123,7 +124,7 @@ pub fn new_variable(input: Span) -> IResult> { tp, exp, range, - comments: vec![], + comments: vec![coms0], } .into(), ) @@ -169,15 +170,16 @@ fn return_statement(input: Span) -> IResult> { delspace(map_res( tuple(( tag_token_word(TokenType::RETURN), + many0(del_newline_or_space!(comment)), opt(general_exp), tag_token_symbol(TokenType::SEMI), opt(delspace(comment)), )), - |((_, range), val, _, optcomment)| { + |((_, range), coms, val, _, optcomment)| { let comments = if let Some(com) = optcomment { - vec![vec![com]] + vec![coms, vec![com]] } else { - vec![vec![]] + vec![coms, vec![]] }; if let Some(val) = val { let range = val.range();