use std::fmt::Display;
use std::vec::IntoIter;
use cairo_lang_filesystem::ids::{FileId, FileKind, FileLongId, SmolStrId, VirtualFile};
use cairo_lang_filesystem::span::TextSpan;
use cairo_lang_primitive_token::{PrimitiveSpan, PrimitiveToken, ToPrimitiveTokenStream};
use cairo_lang_syntax::node::SyntaxNode;
use cairo_lang_test_utils::parse_test_file::TestRunnerResult;
use cairo_lang_utils::Intern;
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use salsa::Database;
use crate::utils::{SimpleParserDatabase, get_syntax_root_and_diagnostics};
pub fn get_diagnostics(
inputs: &OrderedHashMap<String, String>,
_args: &OrderedHashMap<String, String>,
) -> TestRunnerResult {
let db = &SimpleParserDatabase::default();
let code = &inputs["cairo_code"];
let file_id = create_virtual_file(db, "dummy_file.cairo", code);
let (_, diagnostics) = get_syntax_root_and_diagnostics(db, file_id);
TestRunnerResult::success(OrderedHashMap::from([(
"expected_diagnostics".into(),
diagnostics.format(db),
)]))
}
pub fn create_virtual_file<'a>(
db: &'a SimpleParserDatabase,
file_name: impl Into<String>,
content: &str,
) -> FileId<'a> {
FileLongId::Virtual(VirtualFile {
parent: None,
name: SmolStrId::from(db, file_name.into()),
content: SmolStrId::from(db, content),
code_mappings: [].into(),
kind: FileKind::Module,
original_item_removed: false,
})
.intern(db)
}
#[derive(Debug, Clone)]
pub struct MockTokenStream {
pub tokens: Vec<MockToken>,
}
#[derive(Debug, Default, Clone)]
pub struct MockToken {
pub content: String,
pub span: TextSpan,
}
impl MockToken {
pub fn new(content: String, span: TextSpan) -> Self {
Self { content, span }
}
pub fn from_syntax_node(db: &dyn Database, node: SyntaxNode<'_>) -> MockToken {
MockToken::new(node.get_text(db).to_string(), node.span(db))
}
}
impl MockTokenStream {
#[doc(hidden)]
pub fn new(tokens: Vec<MockToken>) -> Self {
Self { tokens }
}
pub fn from_syntax_node(db: &dyn Database, node: SyntaxNode<'_>) -> Self {
let leaves = node.tokens(db);
let tokens = leaves.map(|node| MockToken::from_syntax_node(db, node)).collect();
Self::new(tokens)
}
}
impl Display for MockTokenStream {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for token in &self.tokens {
write!(f, "{}", token.content)?;
}
Ok(())
}
}
impl ToPrimitiveTokenStream for MockTokenStream {
type Iter = IntoIter<PrimitiveToken>;
fn to_primitive_token_stream(&self) -> Self::Iter {
self.tokens
.iter()
.map(|token| {
let span = PrimitiveSpan {
start: token.span.start.as_u32() as usize,
end: token.span.end.as_u32() as usize,
};
PrimitiveToken::new(token.content.clone(), Some(span))
})
.collect::<Vec<_>>()
.into_iter()
}
}