use crate::{
LuaOpKind, LuaSyntaxToken, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVersionNumber,
VisibilityKind,
kind::{BinaryOperator, LuaTokenKind, UnaryOperator},
syntax::{node::token::number_analyzer::NumberResult, traits::LuaAstToken},
};
use super::{float_token_value, int_token_value, string_token_value};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaGeneralToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaGeneralToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(_: LuaTokenKind) -> bool
where
Self: Sized,
{
true
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
Some(LuaGeneralToken { token: syntax })
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaNameToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaNameToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkName
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaNameToken { token: syntax })
} else {
None
}
}
}
impl LuaNameToken {
pub fn get_name_text(&self) -> &str {
self.token.text()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaStringToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaStringToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkString || kind == LuaTokenKind::TkLongString
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaStringToken { token: syntax })
} else {
None
}
}
}
impl LuaStringToken {
pub fn get_value(&self) -> String {
string_token_value(&self.token).unwrap_or_default()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaNumberToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaNumberToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkFloat || kind == LuaTokenKind::TkInt
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaNumberToken { token: syntax })
} else {
None
}
}
}
impl LuaNumberToken {
pub fn is_float(&self) -> bool {
self.token.kind() == LuaTokenKind::TkFloat.into()
}
pub fn is_int(&self) -> bool {
self.token.kind() == LuaTokenKind::TkInt.into()
}
pub fn get_number_value(&self) -> NumberResult {
match self.token.kind().into() {
LuaTokenKind::TkFloat => float_token_value(&self.token)
.map(NumberResult::Float)
.unwrap_or(NumberResult::Float(0.0)),
LuaTokenKind::TkInt => int_token_value(&self.token).unwrap_or(NumberResult::Int(0)),
_ => NumberResult::Int(0),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaBinaryOpToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaBinaryOpToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
LuaOpKind::to_binary_operator(kind) != BinaryOperator::OpNop
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaBinaryOpToken { token: syntax })
} else {
None
}
}
}
impl LuaBinaryOpToken {
pub fn get_op(&self) -> BinaryOperator {
LuaOpKind::to_binary_operator(self.token.kind().into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaUnaryOpToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaUnaryOpToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
LuaOpKind::to_unary_operator(kind) != UnaryOperator::OpNop
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaUnaryOpToken { token: syntax })
} else {
None
}
}
}
impl LuaUnaryOpToken {
pub fn get_op(&self) -> UnaryOperator {
LuaOpKind::to_unary_operator(self.token.kind().into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaKeywordToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaKeywordToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
matches!(
kind,
LuaTokenKind::TkAnd
| LuaTokenKind::TkBreak
| LuaTokenKind::TkDo
| LuaTokenKind::TkElse
| LuaTokenKind::TkElseIf
| LuaTokenKind::TkEnd
| LuaTokenKind::TkFalse
| LuaTokenKind::TkFor
| LuaTokenKind::TkFunction
| LuaTokenKind::TkGoto
| LuaTokenKind::TkIf
| LuaTokenKind::TkIn
| LuaTokenKind::TkLocal
| LuaTokenKind::TkNil
| LuaTokenKind::TkNot
| LuaTokenKind::TkOr
| LuaTokenKind::TkRepeat
| LuaTokenKind::TkReturn
| LuaTokenKind::TkThen
| LuaTokenKind::TkTrue
| LuaTokenKind::TkUntil
| LuaTokenKind::TkWhile
)
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaKeywordToken { token: syntax })
} else {
None
}
}
}
impl LuaKeywordToken {
pub fn get_keyword(&self) -> LuaTokenKind {
self.token.kind().into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaBoolToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaBoolToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkTrue || kind == LuaTokenKind::TkFalse
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaBoolToken { token: syntax })
} else {
None
}
}
}
impl LuaBoolToken {
pub fn is_true(&self) -> bool {
self.token.kind() == LuaTokenKind::TkTrue.into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaNilToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaNilToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkNil
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaNilToken { token: syntax })
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum LuaLiteralToken {
String(LuaStringToken),
Number(LuaNumberToken),
Bool(LuaBoolToken),
Nil(LuaNilToken),
Dots(LuaGeneralToken),
Question(LuaGeneralToken),
}
impl LuaAstToken for LuaLiteralToken {
fn syntax(&self) -> &LuaSyntaxToken {
match self {
LuaLiteralToken::String(token) => token.syntax(),
LuaLiteralToken::Number(token) => token.syntax(),
LuaLiteralToken::Bool(token) => token.syntax(),
LuaLiteralToken::Nil(token) => token.syntax(),
LuaLiteralToken::Dots(token) => token.syntax(),
LuaLiteralToken::Question(token) => token.syntax(),
}
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
matches!(
kind,
LuaTokenKind::TkInt
| LuaTokenKind::TkFloat
| LuaTokenKind::TkComplex
| LuaTokenKind::TkNil
| LuaTokenKind::TkTrue
| LuaTokenKind::TkFalse
| LuaTokenKind::TkDots
| LuaTokenKind::TkString
| LuaTokenKind::TkLongString
| LuaTokenKind::TkDocQuestion
)
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
match syntax.kind().into() {
LuaTokenKind::TkString | LuaTokenKind::TkLongString => {
LuaStringToken::cast(syntax).map(LuaLiteralToken::String)
}
LuaTokenKind::TkFloat | LuaTokenKind::TkInt | LuaTokenKind::TkComplex => {
LuaNumberToken::cast(syntax).map(LuaLiteralToken::Number)
}
LuaTokenKind::TkTrue | LuaTokenKind::TkFalse => {
LuaBoolToken::cast(syntax).map(LuaLiteralToken::Bool)
}
LuaTokenKind::TkNil => LuaNilToken::cast(syntax).map(LuaLiteralToken::Nil),
LuaTokenKind::TkDots => LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Dots),
LuaTokenKind::TkDocQuestion => {
LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Question)
}
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaSpaceToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaSpaceToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
matches!(kind, LuaTokenKind::TkWhitespace | LuaTokenKind::TkEndOfLine)
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaSpaceToken { token: syntax })
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaIndexToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaIndexToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDot
|| kind == LuaTokenKind::TkColon
|| kind == LuaTokenKind::TkLeftBracket
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaIndexToken { token: syntax })
} else {
None
}
}
}
impl LuaIndexToken {
pub fn is_dot(&self) -> bool {
self.token.kind() == LuaTokenKind::TkDot.into()
}
pub fn is_colon(&self) -> bool {
self.token.kind() == LuaTokenKind::TkColon.into()
}
pub fn is_left_bracket(&self) -> bool {
self.token.kind() == LuaTokenKind::TkLeftBracket.into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaDocDetailToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaDocDetailToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDocDetail
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaDocDetailToken { token: syntax })
} else {
None
}
}
}
impl LuaDocDetailToken {
pub fn get_detail(&self) -> &str {
self.token.text()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaDocVisibilityToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaDocVisibilityToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDocVisibility || kind == LuaTokenKind::TkTagVisibility
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaDocVisibilityToken { token: syntax })
} else {
None
}
}
}
impl LuaDocVisibilityToken {
pub fn get_visibility(&self) -> Option<VisibilityKind> {
VisibilityKind::to_visibility_kind(self.token.text())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaDocVersionNumberToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaDocVersionNumberToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDocVersionNumber
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaDocVersionNumberToken { token: syntax })
} else {
None
}
}
}
impl LuaDocVersionNumberToken {
pub fn get_version_number(&self) -> Option<LuaVersionNumber> {
let text = self.token.text();
LuaVersionNumber::from_str(text)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaDocTypeBinaryToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaDocTypeBinaryToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDocOr
|| kind == LuaTokenKind::TkDocAnd
|| kind == LuaTokenKind::TkDocExtends
|| kind == LuaTokenKind::TkDocIn
|| kind == LuaTokenKind::TkDocContinueOr
|| kind == LuaTokenKind::TkPlus
|| kind == LuaTokenKind::TkMinus
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaDocTypeBinaryToken { token: syntax })
} else {
None
}
}
}
impl LuaDocTypeBinaryToken {
pub fn get_op(&self) -> LuaTypeBinaryOperator {
LuaOpKind::to_type_binary_operator(self.token.kind().into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaDocTypeUnaryToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaDocTypeUnaryToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TkDocKeyOf || kind == LuaTokenKind::TkMinus
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaDocTypeUnaryToken { token: syntax })
} else {
None
}
}
}
impl LuaDocTypeUnaryToken {
pub fn get_op(&self) -> LuaTypeUnaryOperator {
LuaOpKind::to_type_unary_operator(self.token.kind().into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LuaPathToken {
token: LuaSyntaxToken,
}
impl LuaAstToken for LuaPathToken {
fn syntax(&self) -> &LuaSyntaxToken {
&self.token
}
fn can_cast(kind: LuaTokenKind) -> bool
where
Self: Sized,
{
kind == LuaTokenKind::TKDocPath
}
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
where
Self: Sized,
{
if Self::can_cast(syntax.kind().into()) {
Some(LuaPathToken { token: syntax })
} else {
None
}
}
}
impl LuaPathToken {
pub fn get_path(&self) -> &str {
let text = self.token.text();
if text.starts_with('\"') || text.starts_with('\'') {
&text[1..text.len() - 1]
} else {
text
}
}
}