#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(nonstandard_style)]
#![allow(unused_imports)]
#![allow(unused_mut)]
#![allow(unused_braces)]
#![allow(unused_parens)]
use std::borrow::Cow;
use std::cmp::{max, min};
use std::ops::{Range, RangeInclusive};
use antlr_rust::parser_rule_context::ParserRuleContext;
use antlr_rust::token::Token;
use antlr_rust::tree::TerminalNode;
use antlr_rust::TidExt;
use crate::antlr::hamelinlexer::HamelinLexer;
use crate::antlr::hamelinparser::HamelinParserContextType;
pub mod hamelinlexer;
pub mod hamelinlistener;
pub mod hamelinparser;
pub mod hamelinvisitor;
pub mod parse;
pub mod trinotypelexer;
pub mod trinotypelistener;
pub mod trinotypeparser;
pub mod trinotypevisitor;
pub use parse::*;
pub fn strip_numeric_separators(s: &str) -> Cow<'_, str> {
if s.contains('_') {
Cow::Owned(s.replace('_', ""))
} else {
Cow::Borrowed(s)
}
}
pub fn completion_interval<'a, PRC>(tree: &PRC) -> RangeInclusive<usize>
where
PRC: ParserRuleContext<'a>,
{
interval_helper(tree, true, None)
}
pub fn cuddled_completion_interval<'a, PRC>(tree: &PRC) -> RangeInclusive<usize>
where
PRC: ParserRuleContext<'a>,
{
interval_helper(tree, true, Some(true))
}
pub fn interval<'a, PRC>(tree: &PRC) -> RangeInclusive<usize>
where
PRC: ParserRuleContext<'a>,
{
interval_helper(tree, false, None)
}
pub fn fit(interval: &RangeInclusive<usize>, s: &str) -> RangeInclusive<usize> {
let max_pos = s.chars().count().saturating_sub(1);
let end = min(*interval.end(), max_pos);
let start = min(*interval.start(), end);
start..=end
}
pub fn fit_cursor(interval: &Range<usize>, s: &str) -> Range<usize> {
let max_pos = s.chars().count();
let end = min(interval.end, max_pos);
let start = min(interval.start, end);
start..end
}
pub fn prepend_space<'a, PRC>(tree: &PRC) -> bool
where
PRC: ParserRuleContext<'a>,
{
let start_token = tree.start();
let stop_token = tree.stop();
if start_token.get_start() > stop_token.get_stop() {
start_token.get_start() == stop_token.get_stop() + 1
} else {
false
}
}
fn can_cuddle(typ: isize) -> bool {
match typ {
hamelinlexer::ARROW
| hamelinlexer::PLUS
| hamelinlexer::MINUS
| hamelinlexer::ASTERISK
| hamelinlexer::SLASH
| hamelinlexer::PERCENT
| hamelinlexer::LCURLY
| hamelinlexer::RCURLY
| hamelinlexer::COLON
| hamelinlexer::QUESTIONMARK
| hamelinlexer::EQ
| hamelinlexer::NEQ
| hamelinlexer::LT
| hamelinlexer::LTE
| hamelinlexer::GT
| hamelinlexer::GTE
| hamelinlexer::RANGE
| hamelinlexer::ASSIGN
| hamelinlexer::COMMA
| hamelinlexer::PIPE
| hamelinlexer::LPARENS
| hamelinlexer::RPARENS
| hamelinlexer::DOT
| hamelinlexer::LBRACKET
| hamelinlexer::RBRACKET => true,
_ => false,
}
}
fn interval_helper<'a, PRC>(
tree: &PRC,
completion: bool,
cuddled: Option<bool>,
) -> RangeInclusive<usize>
where
PRC: ParserRuleContext<'a>,
{
if let Some(tok) = tree.downcast_ref::<TerminalNode<HamelinParserContextType>>() {
return tok.symbol.get_start() as usize..=tok.symbol.get_stop() as usize;
}
let start_token = tree.start();
let stop_token = tree.stop();
if start_token.get_start() > stop_token.get_stop() {
let mut start = start_token.get_start() as usize;
let cuddled = cuddled.unwrap_or_else(|| can_cuddle(stop_token.get_token_type()));
if completion && !cuddled && stop_token.get_stop() as usize + 1 == start {
start += 1;
}
start..=start
} else {
let start = start_token.get_start() as usize;
let mut stop = stop_token.get_stop() as usize;
if completion {
stop += 1;
}
start..=stop
}
}