Keep module docs as one string.

This commit is contained in:
Stephen Chung 2022-07-25 14:11:54 +08:00
parent 148bbcb860
commit 96bfd93610
3 changed files with 42 additions and 21 deletions

View File

@ -2,7 +2,6 @@
use crate::parser::{ParseResult, ParseState}; use crate::parser::{ParseResult, ParseState};
use crate::{Engine, OptimizationLevel, Scope, AST}; use crate::{Engine, OptimizationLevel, Scope, AST};
use std::mem;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -225,9 +224,7 @@ impl Engine {
let mut state = ParseState::new(self, scope, tokenizer_control); let mut state = ParseState::new(self, scope, tokenizer_control);
let mut ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?; let mut ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
ast.set_doc(mem::take( ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n"));
&mut state.tokenizer_control.borrow_mut().global_comments,
));
Ok(ast) Ok(ast)
} }
/// Compile a string containing an expression into an [`AST`], /// Compile a string containing an expression into an [`AST`],

View File

@ -23,7 +23,7 @@ pub struct AST {
source: Identifier, source: Identifier,
/// [`AST`] documentation. /// [`AST`] documentation.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
doc: Vec<SmartString>, doc: SmartString,
/// Global statements. /// Global statements.
body: StmtBlock, body: StmtBlock,
/// Script-defined functions. /// Script-defined functions.
@ -47,7 +47,7 @@ impl fmt::Debug for AST {
fp.field("source", &self.source); fp.field("source", &self.source);
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
fp.field("doc", &self.doc()); fp.field("doc", &self.doc);
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
fp.field("resolver", &self.resolver); fp.field("resolver", &self.resolver);
@ -76,7 +76,7 @@ impl AST {
Self { Self {
source: Identifier::new_const(), source: Identifier::new_const(),
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
doc: Vec::new(), doc: SmartString::new_const(),
body: StmtBlock::new(statements, Position::NONE, Position::NONE), body: StmtBlock::new(statements, Position::NONE, Position::NONE),
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
lib: functions.into(), lib: functions.into(),
@ -96,7 +96,7 @@ impl AST {
Self { Self {
source: Identifier::new_const(), source: Identifier::new_const(),
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
doc: Vec::new(), doc: SmartString::new_const(),
body: StmtBlock::new(statements, Position::NONE, Position::NONE), body: StmtBlock::new(statements, Position::NONE, Position::NONE),
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
lib: functions.into(), lib: functions.into(),
@ -146,7 +146,7 @@ impl AST {
Self { Self {
source: Identifier::new_const(), source: Identifier::new_const(),
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
doc: Vec::new(), doc: SmartString::new_const(),
body: StmtBlock::NONE, body: StmtBlock::NONE,
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
lib: crate::Module::new().into(), lib: crate::Module::new().into(),
@ -187,17 +187,19 @@ impl AST {
self.source.clear(); self.source.clear();
self self
} }
/// Get the documentation. /// Get the documentation (if any).
/// Exported under the `metadata` feature only.
/// ///
/// Only available under `metadata`. /// Documentation is a collection of all comment lines beginning with `//!`.
///
/// Leading white-spaces are stripped, and each line always starts with `//!`.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline(always)] #[inline(always)]
pub fn doc(&self) -> String { pub fn doc(&self) -> &str {
self.doc.join("\n") &self.doc
} }
/// Clear the documentation. /// Clear the documentation.
/// /// Exported under the `metadata` feature only.
/// Only available under `metadata`.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline(always)] #[inline(always)]
pub fn clear_doc(&mut self) -> &mut Self { pub fn clear_doc(&mut self) -> &mut Self {
@ -209,7 +211,7 @@ impl AST {
/// Only available under `metadata`. /// Only available under `metadata`.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline(always)] #[inline(always)]
pub(crate) fn doc_mut(&mut self) -> &mut Vec<SmartString> { pub(crate) fn doc_mut(&mut self) -> &mut SmartString {
&mut self.doc &mut self.doc
} }
/// Set the documentation. /// Set the documentation.
@ -217,8 +219,8 @@ impl AST {
/// Only available under `metadata`. /// Only available under `metadata`.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
#[inline(always)] #[inline(always)]
pub(crate) fn set_doc(&mut self, doc: Vec<SmartString>) { pub(crate) fn set_doc(&mut self, doc: impl Into<SmartString>) {
self.doc = doc; self.doc = doc.into();
} }
/// Get the statements. /// Get the statements.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
@ -588,7 +590,12 @@ impl AST {
} }
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
_ast.doc.extend(other.doc.iter().cloned()); if !other.doc.is_empty() {
if !_ast.doc.is_empty() {
_ast.doc.push('\n');
}
_ast.doc.push_str(other.doc());
}
_ast _ast
} }
@ -684,7 +691,12 @@ impl AST {
} }
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
self.doc.extend(other.doc.into_iter()); if !other.doc.is_empty() {
if !self.doc.is_empty() {
self.doc.push('\n');
}
self.doc.push_str(&other.doc);
}
self self
} }

View File

@ -45,6 +45,16 @@ pub struct ScriptFnDef {
pub params: StaticVec<Identifier>, pub params: StaticVec<Identifier>,
/// _(metadata)_ Function doc-comments (if any). /// _(metadata)_ Function doc-comments (if any).
/// Exported under the `metadata` feature only. /// Exported under the `metadata` feature only.
///
/// Doc-comments are comment lines beginning with `///` or comment blocks beginning with `/**`,
/// placed immediately before a function definition.
///
/// 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 `/**`.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
pub comments: Box<[Box<str>]>, pub comments: Box<[Box<str>]>,
} }
@ -85,13 +95,15 @@ pub struct ScriptFnMetadata<'a> {
/// _(metadata)_ Function doc-comments (if any). /// _(metadata)_ Function doc-comments (if any).
/// Exported under the `metadata` feature only. /// Exported under the `metadata` feature only.
/// ///
/// Doc-comments are comment lines beginning with `///` or comment blocks beginning with `/**`,
/// placed immediately before a function definition.
///
/// Block doc-comments are kept in a single string slice with line-breaks within. /// 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. /// 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 /// Leading white-spaces are stripped, and each string slice always starts with the
/// corresponding doc-comment leader: `///` or `/**`. /// corresponding doc-comment leader: `///` or `/**`.
/// Function access mode.
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
pub comments: Vec<&'a str>, pub comments: Vec<&'a str>,
} }