use std::any::Any;
use tower_lsp::lsp_types::SemanticToken;
use tower_lsp::lsp_types::SemanticTokenType;
use crate::document::document::Document;
use crate::document::element::Element;
use crate::elements::comment::Comment;
use crate::elements::paragraph::Paragraph;
use crate::elements::section::Section;
use crate::parser::rule::Rule;
use super::parser::LineCursor;
pub trait SemanticProvider: Rule {
fn get_semantic_tokens(
&self,
cursor: &LineCursor,
match_data: Box<dyn Any>,
) -> Vec<SemanticToken>;
}
pub mod nml_semantic {
use tower_lsp::lsp_types::SemanticTokenType;
pub const SECTION_HEADING: SemanticTokenType = SemanticTokenType::new("type");
pub const SECTION_NAME: SemanticTokenType = SemanticTokenType::new("string");
pub const REFERENCE: SemanticTokenType = SemanticTokenType::new("event");
}
pub const LEGEND_TYPE: &[SemanticTokenType] = &[
SemanticTokenType::COMMENT,
SemanticTokenType::VARIABLE,
SemanticTokenType::STRING,
SemanticTokenType::PARAMETER,
];
// TODO...
pub fn provide(
semantic_tokens: &mut Vec<SemanticToken>,
cursor: &mut LineCursor,
elem: &Box<dyn Element>,
) {
if cursor.source != elem.location().source() {
return;
}
let prev = cursor.clone();
/*if let Some(comm) = elem.downcast_ref::<Comment>() {
cursor.at(elem.location().start());
let delta_start = if cursor.line == prev.line {
cursor.line_pos - prev.line_pos
} else if cursor.line == 0 {
cursor.line_pos
} else {
cursor.line_pos + 1
};
semantic_tokens.push(SemanticToken {
delta_line: (cursor.line - prev.line) as u32,
delta_start: delta_start as u32,
length: (elem.location().end() - elem.location().start()) as u32,
token_type: 0,
token_modifiers_bitset: 0,
});
} else */if let Some(sect) = elem.downcast_ref::<Section>() {
cursor.at(elem.location().start() + 1);
eprintln!("section {cursor:#?}");
let delta_start = if cursor.line == prev.line {
cursor.line_pos - prev.line_pos
} else if cursor.line == 0 {
cursor.line_pos
} else {
0
};
semantic_tokens.push(SemanticToken {
delta_line: (cursor.line - prev.line) as u32,
delta_start: delta_start as u32,
length: (elem.location().end() - elem.location().start()) as u32,
token_type: 0,
token_modifiers_bitset: 0,
});
}
}
pub fn semantic_token_from_document(document: &dyn Document) -> Vec<SemanticToken> {
let mut semantic_tokens = vec![];
let source = document.source();
let mut cursor = LineCursor {
pos: 0,
line: 0,
line_pos: 0,
source: source.clone(),
};
/*
semantic_tokens.push(SemanticToken {
delta_line: 2,
delta_start: 1,
length: 5,
token_type: 0,
token_modifiers_bitset: 0,
});
semantic_tokens.push(SemanticToken {
delta_line: 1,
delta_start: 1,
length: 5,
token_type: 1,
token_modifiers_bitset: 0,
});*/
document.content().borrow()
.iter()
.for_each(|elem| {
if let Some(container) = elem.as_container()
{
container
.contained()
.iter()
.for_each(|elem| provide(&mut semantic_tokens, &mut cursor, elem));
}
else
{
provide(&mut semantic_tokens, &mut cursor, elem);
}
});
semantic_tokens
}