use crate::ast;
use std::borrow::Cow;
fn script_lang<'s>(script: &ast::Script<'_>, source: &'s str) -> Option<&'s str> {
for attr_node in script.attributes {
let ast::AttributeNode::Attribute(attr) = attr_node else {
continue;
};
let name = attr.name(source);
if name == "lang"
&& let Some(values) = &attr.value
&& let Some(ast::AttributeValue::Text(text)) = values.first()
{
return Some(text.raw(source));
}
}
None
}
pub(super) fn component_is_typescript(root: &ast::Root<'_>, source: &str) -> bool {
let mut scripts = [root.module, root.instance];
scripts.sort_by_key(|s| s.map_or(u32::MAX, |script| script.span.start));
scripts
.into_iter()
.flatten()
.find_map(|script| script_lang(script, source))
.is_some_and(|lang| lang == "ts")
}
pub(super) fn find_option_values<'arena>(
attrs: &[ast::AttributeNode<'arena>],
name: &str,
source: &str,
) -> Option<&'arena [ast::AttributeValue<'arena>]> {
attrs.iter().find_map(|attr| {
if let ast::AttributeNode::Attribute(attr) = attr
&& attr.name(source) == name
{
attr.value
} else {
None
}
})
}
pub(super) fn text_value<'src>(
values: &[ast::AttributeValue<'_>],
source: &'src str,
) -> Option<Cow<'src, str>> {
values.iter().find_map(|v| {
if let ast::AttributeValue::Text(text) = v {
Some(text.data(source))
} else {
None
}
})
}
pub(super) fn bool_option(
attrs: &[ast::AttributeNode<'_>],
name: &str,
source: &str,
) -> Option<bool> {
attrs.iter().find_map(|attr| {
if let ast::AttributeNode::Attribute(attr) = attr
&& attr.name(source) == name
{
match &attr.value {
None => Some(true),
Some(values) => values.iter().find_map(|v| {
if let ast::AttributeValue::ExpressionTag(expr) = v
&& let tsv_ts::ast::ExpressionKind::Literal(lit) = &expr.expression.kind
&& let tsv_ts::ast::LiteralValue::Boolean(b) = lit.value
{
Some(b)
} else {
None
}
}),
}
} else {
None
}
})
}