#![allow(unused_unsafe)]
use std::fmt;
use std::mem;
use std::marker::{PhantomData};
use clang_sys::*;
use utility;
use super::{TranslationUnit};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CommentChild {
BlockCommand(BlockCommand),
HtmlStartTag(HtmlStartTag),
HtmlEndTag(String),
InlineCommand(InlineCommand),
Paragraph(Vec<CommentChild>),
ParamCommand(ParamCommand),
TParamCommand(TParamCommand),
Text(String),
VerbatimCommand(Vec<String>),
VerbatimLineCommand(String),
}
impl CommentChild {
fn from_raw(raw: CXComment) -> CommentChild {
unsafe {
match clang_Comment_getKind(raw) {
CXComment_Text =>
CommentChild::Text(utility::to_string(clang_TextComment_getText(raw))),
CXComment_InlineCommand =>
CommentChild::InlineCommand(InlineCommand::from_raw(raw)),
CXComment_HTMLStartTag => CommentChild::HtmlStartTag(HtmlStartTag::from_raw(raw)),
CXComment_HTMLEndTag => {
let name = utility::to_string(clang_HTMLTagComment_getTagName(raw));
CommentChild::HtmlEndTag(name)
},
CXComment_Paragraph =>
CommentChild::Paragraph(Comment::from_raw(raw).get_children()),
CXComment_BlockCommand => CommentChild::BlockCommand(BlockCommand::from_raw(raw)),
CXComment_ParamCommand => CommentChild::ParamCommand(ParamCommand::from_raw(raw)),
CXComment_TParamCommand =>
CommentChild::TParamCommand(TParamCommand::from_raw(raw)),
CXComment_VerbatimBlockCommand => {
let lines = iter!(
clang_Comment_getNumChildren(raw),
clang_Comment_getChild(raw),
).map(|c| {
utility::to_string(clang_VerbatimBlockLineComment_getText(c))
}).collect();
CommentChild::VerbatimCommand(lines)
},
CXComment_VerbatimLine => {
let line = utility::to_string(clang_VerbatimLineComment_getText(raw));
CommentChild::VerbatimLineCommand(line)
},
_ => unreachable!(),
}
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub enum ParameterDirection {
In = 0,
Out = 1,
InOut = 2,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub enum InlineCommandStyle {
Bold = 1,
Monospace = 2,
Emphasized = 3,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BlockCommand {
pub command: String,
pub arguments: Vec<String>,
pub children: Vec<CommentChild>,
}
impl BlockCommand {
unsafe fn from_raw(raw: CXComment) -> BlockCommand {
let command = utility::to_string(clang_BlockCommandComment_getCommandName(raw));
let arguments = iter!(
clang_BlockCommandComment_getNumArgs(raw),
clang_BlockCommandComment_getArgText(raw),
).map(utility::to_string).collect();
let paragraph = clang_BlockCommandComment_getParagraph(raw);
let children = Comment::from_raw(paragraph).get_children();
BlockCommand { command, arguments, children }
}
}
#[derive(Copy, Clone)]
pub struct Comment<'tu> {
raw: CXComment,
_marker: PhantomData<&'tu TranslationUnit<'tu>>,
}
impl<'tu> Comment<'tu> {
#[doc(hidden)]
pub fn from_raw(raw: CXComment) -> Comment<'tu> {
Comment { raw, _marker: PhantomData }
}
pub fn get_children(&self) -> Vec<CommentChild> {
iter!(
clang_Comment_getNumChildren(self.raw),
clang_Comment_getChild(self.raw),
).map(CommentChild::from_raw).collect()
}
pub fn as_html(&self) -> String {
unsafe { utility::to_string(clang_FullComment_getAsHTML(self.raw)) }
}
pub fn as_xml(&self) -> String {
unsafe { utility::to_string(clang_FullComment_getAsXML(self.raw)) }
}
}
impl<'tu> fmt::Debug for Comment<'tu> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{:?}", self.get_children())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct HtmlStartTag {
pub name: String,
pub attributes: Vec<(String, String)>,
pub closing: bool,
}
impl HtmlStartTag {
unsafe fn from_raw(raw: CXComment) -> HtmlStartTag {
let name = utility::to_string(clang_HTMLTagComment_getTagName(raw));
let attributes = iter!(
clang_HTMLStartTag_getNumAttrs(raw),
clang_HTMLStartTag_getAttrName(raw),
clang_HTMLStartTag_getAttrValue(raw),
).map(|(n, v)| (utility::to_string(n), utility::to_string(v))).collect();
let closing = clang_HTMLStartTagComment_isSelfClosing(raw) != 0;
HtmlStartTag { name, attributes, closing }
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InlineCommand {
pub command: String,
pub arguments: Vec<String>,
pub style: Option<InlineCommandStyle>,
}
impl InlineCommand {
unsafe fn from_raw(raw: CXComment) -> InlineCommand {
let command = utility::to_string(clang_InlineCommandComment_getCommandName(raw));
let arguments = iter!(
clang_InlineCommandComment_getNumArgs(raw),
clang_InlineCommandComment_getArgText(raw),
).map(utility::to_string).collect();
let style = match clang_InlineCommandComment_getRenderKind(raw) {
CXCommentInlineCommandRenderKind_Normal => None,
other => Some(mem::transmute(other)),
};
InlineCommand { command, arguments, style }
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParamCommand {
pub index: Option<usize>,
pub parameter: String,
pub direction: Option<ParameterDirection>,
pub children: Vec<CommentChild>
}
impl ParamCommand {
unsafe fn from_raw(raw: CXComment) -> ParamCommand {
let index = if clang_ParamCommandComment_isParamIndexValid(raw) != 0 {
Some(clang_ParamCommandComment_getParamIndex(raw) as usize)
} else {
None
};
let parameter = utility::to_string(clang_ParamCommandComment_getParamName(raw));
let direction = if clang_ParamCommandComment_isDirectionExplicit(raw) != 0 {
Some(mem::transmute(clang_ParamCommandComment_getDirection(raw)))
} else {
None
};
let paragraph = clang_BlockCommandComment_getParagraph(raw);
let children = Comment::from_raw(paragraph).get_children();
ParamCommand { index, parameter, direction, children }
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TParamCommand {
pub position: Option<(usize, usize)>,
pub parameter: String,
pub children: Vec<CommentChild>
}
impl TParamCommand {
unsafe fn from_raw(raw: CXComment) -> TParamCommand {
let position = if clang_TParamCommandComment_isParamPositionValid(raw) != 0 {
let depth = clang_TParamCommandComment_getDepth(raw);
let index = clang_TParamCommandComment_getIndex(raw, depth) as usize;
Some((depth as usize, index))
} else {
None
};
let parameter = utility::to_string(clang_TParamCommandComment_getParamName(raw));
let paragraph = clang_BlockCommandComment_getParagraph(raw);
let children = Comment::from_raw(paragraph).get_children();
TParamCommand { position, parameter, children }
}
}