From 882b26d2a14bfbb5cf6a2122f42a45911366873e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 18 Dec 2020 16:31:44 +0800 Subject: [PATCH] Change ScriptFnMetadata to hold references. --- src/ast.rs | 51 +++++++++++++++++++++++++++++-------------------- src/dynamic.rs | 2 +- src/optimize.rs | 2 +- src/parser.rs | 24 +++++++++++------------ 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index e9823156..75435825 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -83,8 +83,8 @@ pub struct ScriptFnDef { /// Access to external variables. #[cfg(not(feature = "no_closure"))] pub externals: Vec, - /// Comment block for function. - pub fn_comments: Vec, + /// Function doc-comments (if any). + pub comments: Vec, } impl fmt::Display for ScriptFnDef { @@ -107,16 +107,29 @@ impl fmt::Display for ScriptFnDef { } } -/// A type containing a script-defined function's metadata. -#[derive(Debug, Clone, Hash)] -pub struct ScriptFnMetadata { - pub comments: Vec, +/// A type containing the metadata of a script-defined function. +/// +/// Created by [`AST::iter_functions`]. +#[derive(Debug, Eq, PartialEq, Clone, Hash)] +pub struct ScriptFnMetadata<'a> { + /// Function doc-comments (if any). + /// + /// Block doc-comments are kept in a single string slice with line-breaks within. + /// + /// Line doc-comments are kept in one string slice per line without the termination line-break. + /// + /// Leading white-spaces are stripped, and each string slice always starts with the corresponding + /// doc-comment leader: `///` or `/**`. + pub comments: Vec<&'a str>, + /// Function access mode. pub access: FnAccess, - pub fn_name: ImmutableString, - pub params: Vec, + /// Function name. + pub name: &'a str, + /// Function parameters (if any). + pub params: Vec<&'a str>, } -impl fmt::Display for ScriptFnMetadata { +impl fmt::Display for ScriptFnMetadata<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, @@ -126,23 +139,19 @@ impl fmt::Display for ScriptFnMetadata { } else { "" }, - self.fn_name, - self.params - .iter() - .map(|p| p.as_str()) - .collect::>() - .join(", ") + self.name, + self.params.iter().cloned().collect::>().join(", ") ) } } -impl Into for &ScriptFnDef { - fn into(self) -> ScriptFnMetadata { +impl<'a> Into> for &'a ScriptFnDef { + fn into(self) -> ScriptFnMetadata<'a> { ScriptFnMetadata { - comments: self.fn_comments.clone(), + comments: self.comments.iter().map(|s| s.as_str()).collect(), access: self.access, - fn_name: self.name.clone(), - params: self.params.iter().cloned().collect(), + name: &self.name, + params: self.params.iter().map(|s| s.as_str()).collect(), } } } @@ -538,7 +547,7 @@ impl AST { } self } - /// Iterate through all functions + /// Iterate through all function definitions. #[cfg(not(feature = "no_function"))] #[inline(always)] pub fn iter_functions<'a>(&'a self) -> impl Iterator + 'a { diff --git a/src/dynamic.rs b/src/dynamic.rs index 41f2756e..c6efb8b8 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -503,7 +503,7 @@ impl Clone for Dynamic { /// /// ## WARNING /// - /// The cloned copy is marked [`AccessType::Normal`] even if the original is constant. + /// The cloned copy is marked read-write even if the original is read-only. fn clone(&self) -> Self { match self.0 { Union::Unit(value, _) => Self(Union::Unit(value, AccessMode::ReadWrite)), diff --git a/src/optimize.rs b/src/optimize.rs index 2ef94938..53be762e 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -868,7 +868,7 @@ pub fn optimize_into_ast( lib: None, #[cfg(not(feature = "no_module"))] mods: Default::default(), - fn_comments: Default::default(), + comments: Default::default(), }) .for_each(|fn_def| { lib2.set_script_fn(fn_def); diff --git a/src/parser.rs b/src/parser.rs index afd0dd5f..f0003abd 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2409,14 +2409,14 @@ fn parse_stmt( ) -> Result, ParseError> { use AccessMode::{ReadOnly, ReadWrite}; - let mut fn_comments: Vec = Default::default(); - let mut fn_comments_pos = Position::NONE; + let mut comments: Vec = Default::default(); + let mut comments_pos = Position::NONE; - // Handle doc-comment. + // Handle doc-comments. #[cfg(not(feature = "no_function"))] while let (Token::Comment(ref comment), comment_pos) = input.peek().unwrap() { - if fn_comments_pos.is_none() { - fn_comments_pos = *comment_pos; + if comments_pos.is_none() { + comments_pos = *comment_pos; } if !is_doc_comment(comment) { @@ -2424,16 +2424,16 @@ fn parse_stmt( } if !settings.is_global { - return Err(PERR::WrongDocComment.into_err(fn_comments_pos)); + return Err(PERR::WrongDocComment.into_err(comments_pos)); } if let Token::Comment(comment) = input.next().unwrap().0 { - fn_comments.push(comment); + comments.push(comment); match input.peek().unwrap() { (Token::Fn, _) | (Token::Private, _) => break, (Token::Comment(_), _) => (), - _ => return Err(PERR::WrongDocComment.into_err(fn_comments_pos)), + _ => return Err(PERR::WrongDocComment.into_err(comments_pos)), } } else { unreachable!(); @@ -2492,7 +2492,7 @@ fn parse_stmt( pos: pos, }; - let func = parse_fn(input, &mut new_state, lib, access, settings, fn_comments)?; + let func = parse_fn(input, &mut new_state, lib, access, settings, comments)?; // Qualifiers (none) + function name + number of arguments. let hash = calc_script_fn_hash(empty(), &func.name, func.params.len()); @@ -2651,7 +2651,7 @@ fn parse_fn( lib: &mut FunctionsLib, access: FnAccess, mut settings: ParseSettings, - fn_comments: Vec, + comments: Vec, ) -> Result { #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2737,7 +2737,7 @@ fn parse_fn( lib: None, #[cfg(not(feature = "no_module"))] mods: Default::default(), - fn_comments, + comments, }) } @@ -2894,7 +2894,7 @@ fn parse_anon_fn( lib: None, #[cfg(not(feature = "no_module"))] mods: Default::default(), - fn_comments: Default::default(), + comments: Default::default(), }; let expr = Expr::FnPointer(fn_name, settings.pos);