From 9a28c8a2a6ba3dd2b77e41f41c9a453d1b64fbc4 Mon Sep 17 00:00:00 2001 From: numToStr <24727447+numToStr@users.noreply.github.com> Date: Thu, 27 Oct 2022 17:23:45 +0530 Subject: [PATCH] chore: don't tokenize extraneous stuff (#57) Also fixed a bug that slipped through in #56 :p --- README.md | 11 ++++++----- src/cli.rs | 6 +++--- src/lexer.rs | 39 +++++++++++---------------------------- src/lexer/token.rs | 21 ++++++++++++++++----- src/lib.rs | 4 ++-- src/parser/node.rs | 6 +++++- src/parser/tags/class.rs | 7 ++++++- src/parser/tags/func.rs | 27 ++++++++++++--------------- src/parser/tags/type.rs | 7 ------- src/vimdoc/class.rs | 14 ++++---------- src/vimdoc/func.rs | 14 ++++---------- tests/with_settings.rs | 12 ++++++++---- 12 files changed, 77 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index abca80f..fd5799a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ To properly generate docs you should follow emmylua spec. The parser is capable Using the CLI is simple just give it the path to the lua files; it will parse them and prints the help doc to **stdout** ```bash -lemmy-help /path/to/{first,second,third}.lua > doc.txt +lemmy-help /path/to/{first,second,third}.lua > doc/PLUGIN_NAME.txt ``` ### Cli @@ -55,17 +55,18 @@ ARGS: ... Path to the files FLAGS: + -h, --help Print help information + -v, --version Print version information -M, --no-modeline Don't print modeline at the end -f, --prefix-func Prefix function name with ---@mod name -a, --prefix-alias Prefix ---@alias tag with return/---@mod name -c, --prefix-class Prefix ---@class tag with return/---@mod name -t, --prefix-type Prefix ---@type tag with ---@mod name - -h, --help Print help information - -v, --version Print version information + --expand-opt Expand '?' (optional) to 'nil' type USAGE: - lemmy-help /path/to/first.lua /path/to/second.lua > doc.txt - lemmy-help -c -a /path/to/{first,second,third}.lua > doc.txt + lemmy-help /path/to/first.lua /path/to/second.lua > doc/PLUGIN_NAME.txt + lemmy-help -c -a /path/to/{first,second,third}.lua > doc/PLUGIN_NAME.txt NOTES: - The order of parsing + rendering is relative to the given files diff --git a/src/cli.rs b/src/cli.rs index 9b942b6..01c8789 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -104,11 +104,11 @@ FLAGS: -a, --prefix-alias Prefix ---@alias tag with return/---@mod name -c, --prefix-class Prefix ---@class tag with return/---@mod name -t, --prefix-type Prefix ---@type tag with ---@mod name - --expand-opt Expand ? (optional) to nil + --expand-opt Expand '?' (optional) to 'nil' type USAGE: - {NAME} /path/to/first.lua /path/to/second.lua > doc.txt - {NAME} -c -a /path/to/{{first,second,third}}.lua > doc.txt + {NAME} /path/to/first.lua /path/to/second.lua > doc/PLUGIN_NAME.txt + {NAME} -c -a /path/to/{{first,second,third}}.lua > doc/PLUGIN_NAME.txt NOTES: - The order of parsing + rendering is relative to the given files diff --git a/src/lexer.rs b/src/lexer.rs index e38baea..105ae86 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -258,17 +258,14 @@ impl Lexer { .map(TagType::Export), ))); - let local = keyword("local").padded(); let func = keyword("function").padded(); + let ret = keyword("return"); let assign = just('=').padded(); - let dotted = choice(( - ident() - .then(choice((just('.').to(Kind::Dot), just(':').to(Kind::Colon)))) - .then(ident()) - .map(|((prefix, scope), name)| (Some(prefix), scope, name)), - ident().map(|name| (None, Kind::Local, name)), - )); + let dotted = ident() + .then(choice((just('.').to(Kind::Dot), just(':').to(Kind::Colon)))) + .then(ident()) + .map(|((prefix, scope), name)| (Some(prefix), scope, name)); let expr = dotted.clone().then_ignore(assign); @@ -279,29 +276,15 @@ impl Lexer { newline().to(TagType::Comment(String::new())), comment.map(TagType::Comment), ))), - local.ignore_then(choice(( - func.clone().ignore_then(ident()).map(|name| TagType::Func { - name, - prefix: None, - kind: Kind::Local, - }), - ident().then_ignore(assign).map(|name| TagType::Expr { - name, - prefix: None, - kind: Kind::Local, - }), - ))), func.clone() .ignore_then(dotted) .map(|(prefix, kind, name)| TagType::Func { prefix, name, kind }), - choice(( - expr.clone() - .then_ignore(func) - .map(|(prefix, kind, name)| TagType::Func { prefix, name, kind }), - expr.map(|(prefix, kind, name)| TagType::Expr { prefix, name, kind }), - )), - keyword("return") - .ignore_then(ident().padded()) + expr.then(func.or_not()) + .map(|((prefix, kind, name), is_func)| match is_func { + Some(_) => TagType::Func { prefix, name, kind }, + None => TagType::Expr { prefix, name, kind }, + }), + ret.ignore_then(ident().padded()) .then_ignore(end()) .map(TagType::Export), till_eol.to(TagType::Skip), diff --git a/src/lexer/token.rs b/src/lexer/token.rs index 16e9256..a2c2845 100644 --- a/src/lexer/token.rs +++ b/src/lexer/token.rs @@ -110,7 +110,6 @@ pub enum TagType { pub enum Kind { Dot, Colon, - Local, } impl Kind { @@ -118,7 +117,6 @@ impl Kind { match self { Self::Dot => '.', Self::Colon => ':', - Self::Local => '#', } } } @@ -192,9 +190,18 @@ impl Display for Ty { Self::Userdata => f.write_str("userdata"), Self::Lightuserdata => f.write_str("lightuserdata"), Self::Ref(id) => f.write_str(id), - Self::Array(ty) => write!(f, "{ty}[]"), + Self::Array(ty) => { + f.write_str(&ty.to_string())?; + f.write_str("[]") + } Self::Table(kv) => match kv { - Some((k, v)) => write!(f, "table<{k},{v}>"), + Some((k, v)) => { + f.write_str("table<")?; + f.write_str(&k.to_string())?; + f.write_str(",")?; + f.write_str(&v.to_string())?; + f.write_str(">") + } None => f.write_str("table"), }, Self::Fun(args, ret) => { @@ -217,7 +224,11 @@ impl Display for Ty { f.write_str(&list_like(kv))?; f.write_str("}") } - Self::Union(rhs, lhs) => write!(f, "{rhs}|{lhs}"), + Self::Union(rhs, lhs) => { + f.write_str(&rhs.to_string())?; + f.write_str("|")?; + f.write_str(&lhs.to_string()) + } } } } diff --git a/src/lib.rs b/src/lib.rs index 39cf55d..5dbace3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,7 +114,7 @@ impl LemmyHelp { match ele { Node::Export(..) => {} Node::Func(mut func) => { - if func.is_public(&export) { + if func.prefix.left.as_deref() == Some(&export) { if settings.prefix_func { func.prefix.right = Some(module.to_owned()); } @@ -122,7 +122,7 @@ impl LemmyHelp { } } Node::Type(mut typ) => { - if typ.is_public(&export) { + if typ.prefix.left.as_deref() == Some(&export) { if settings.prefix_type { typ.prefix.right = Some(module.to_owned()); } diff --git a/src/parser/node.rs b/src/parser/node.rs index ec6875f..83d67c6 100644 --- a/src/parser/node.rs +++ b/src/parser/node.rs @@ -45,6 +45,10 @@ impl_parse!(Node, Option, { }); impl Node { + fn init() -> impl Parser, Error = Simple> { + Node::parse().repeated().flatten() + } + /// Creates stream of AST nodes from emmylua /// /// ``` @@ -68,6 +72,6 @@ impl Node { let tokens = Lexer::init().parse(src).unwrap(); let stream = Stream::from_iter(src.len()..src.len() + 1, tokens.into_iter()); - Node::parse().repeated().flatten().parse(stream) + Node::init().parse(stream) } } diff --git a/src/parser/tags/class.rs b/src/parser/tags/class.rs index 320375a..185b7ae 100644 --- a/src/parser/tags/class.rs +++ b/src/parser/tags/class.rs @@ -23,7 +23,12 @@ impl_parse!(Field, { }) .map(|(header, (scope, name, ty, desc))| { let desc = match desc { - Some(d) => vec![d], + Some(d) => { + let mut new_desc = Vec::with_capacity(header.len() + 1); + new_desc.push(d); + new_desc.extend(header); + new_desc + } None => header, }; diff --git a/src/parser/tags/func.rs b/src/parser/tags/func.rs index 142bc27..2ac699a 100644 --- a/src/parser/tags/func.rs +++ b/src/parser/tags/func.rs @@ -21,10 +21,12 @@ impl_parse!(Param, { .then(select! { TagType::Comment(x) => x }.repeated()) .map(|((name, ty, desc), extra)| { let desc = match desc { - Some(d) => Vec::from([d]) - .into_iter() - .chain(extra.into_iter()) - .collect(), + Some(d) => { + let mut new_desc = Vec::with_capacity(extra.len() + 1); + new_desc.push(d); + new_desc.extend(extra); + new_desc + } None => extra, }; Self { name, ty, desc } @@ -45,10 +47,12 @@ impl_parse!(Return, { .then(select! { TagType::Comment(x) => x }.repeated()) .map(|((ty, name, desc), extra)| { let desc = match desc { - Some(d) => Vec::from([d]) - .into_iter() - .chain(extra.into_iter()) - .collect(), + Some(d) => { + let mut new_desc = Vec::with_capacity(extra.len() + 1); + new_desc.push(d); + new_desc.extend(extra); + new_desc + } None => extra, }; @@ -94,10 +98,3 @@ impl_parse!(Func, { }, ) }); - -impl Func { - #[inline] - pub fn is_public(&self, export: &str) -> bool { - self.kind != Kind::Local && self.prefix.left.as_deref() == Some(export) - } -} diff --git a/src/parser/tags/type.rs b/src/parser/tags/type.rs index a5e1835..67c4ee6 100644 --- a/src/parser/tags/type.rs +++ b/src/parser/tags/type.rs @@ -42,10 +42,3 @@ impl_parse!(Type, { }, ) }); - -impl Type { - #[inline] - pub fn is_public(&self, export: &str) -> bool { - self.kind != Kind::Local && self.prefix.left.as_deref() == Some(export) - } -} diff --git a/src/vimdoc/class.rs b/src/vimdoc/class.rs index c2b30ea..f50d5dc 100644 --- a/src/vimdoc/class.rs +++ b/src/vimdoc/class.rs @@ -30,19 +30,13 @@ impl ToDoc for ClassDoc { let mut table = Table::new(); for field in &n.fields { - let n = match (s.expand_opt, &field.name) { - (true, Name::Req(n) | Name::Opt(n)) => format!("{{{n}}}"), - (false, n) => format!("{{{n}}}"), - }; - - let t = if s.expand_opt { - format!("(nil|{})", field.ty) - } else { - format!("({})", field.ty) + let (name, ty) = match (s.expand_opt, &field.name) { + (true, Name::Opt(n)) => (format!("{{{n}}}"), format!("(nil|{})", field.ty)), + (_, n) => (format!("{{{n}}}"), format!("({})", field.ty)), }; if field.scope == Scope::Public { - table.add_row([n, t, field.desc.join("\n")]); + table.add_row([name, ty, field.desc.join("\n")]); } } diff --git a/src/vimdoc/func.rs b/src/vimdoc/func.rs index b006aa8..f3f96ef 100644 --- a/src/vimdoc/func.rs +++ b/src/vimdoc/func.rs @@ -55,18 +55,12 @@ impl ToDoc for FuncDoc { let mut table = Table::new(); for param in &n.params { - let n = match (s.expand_opt, ¶m.name) { - (true, Name::Req(n) | Name::Opt(n)) => format!("{{{n}}}"), - (false, n) => format!("{{{n}}}"), + let (name, ty) = match (s.expand_opt, ¶m.name) { + (true, Name::Opt(n)) => (format!("{{{n}}}"), format!("(nil|{})", param.ty)), + (_, n) => (format!("{{{n}}}"), format!("({})", param.ty)), }; - let t = if s.expand_opt { - format!("(nil|{})", param.ty) - } else { - format!("({})", param.ty) - }; - - table.add_row([n, t, param.desc.join("\n")]); + table.add_row([name, ty, param.desc.join("\n")]); } doc.push_str(&table.to_string()); diff --git a/tests/with_settings.rs b/tests/with_settings.rs index 93de0fe..0d6185a 100644 --- a/tests/with_settings.rs +++ b/tests/with_settings.rs @@ -143,10 +143,12 @@ local M = {} ---@class HelloWorld ---@field message? string First message to the world ---@field private opts? table +---@field secret table Sauce ---Prints given value ----@param message? string -function M.echo(message) +---@param message string +---@param opts? table +function M.echo(message, opts) return print(message) end @@ -168,13 +170,15 @@ HelloWorld *HelloWorld* Fields: ~ {message} (nil|string) First message to the world + {secret} (table) Sauce -M.echo({message?}) *M.echo* +M.echo({message}, {opts?}) *M.echo* Prints given value Parameters: ~ - {message} (nil|string) + {message} (string) + {opts} (nil|table) "