lisette-syntax 0.1.4

Little language inspired by Rust that compiles to Go
Documentation
use rustc_hash::FxHashMap as HashMap;

use ecow::EcoString;

use crate::ast::{
    Annotation, EnumVariant, Generic, Span, StructFieldDefinition, StructKind, ValueEnumVariant,
};
use crate::types::Type;

#[derive(Debug, Clone)]
pub enum Definition {
    TypeAlias {
        visibility: Visibility,
        name: EcoString,
        name_span: Span,
        generics: Vec<Generic>,
        annotation: Annotation,
        ty: Type,
        methods: MethodSignatures,
        doc: Option<String>,
    },
    Enum {
        visibility: Visibility,
        ty: Type,
        name: EcoString,
        name_span: Span,
        generics: Vec<Generic>,
        variants: Vec<EnumVariant>,
        methods: MethodSignatures,
        doc: Option<String>,
    },
    ValueEnum {
        visibility: Visibility,
        ty: Type,
        name: EcoString,
        name_span: Span,
        variants: Vec<ValueEnumVariant>,
        underlying_ty: Option<Type>,
        methods: MethodSignatures,
        doc: Option<String>,
    },
    Struct {
        visibility: Visibility,
        ty: Type,
        name: EcoString,
        name_span: Span,
        generics: Vec<Generic>,
        fields: Vec<StructFieldDefinition>,
        kind: StructKind,
        methods: MethodSignatures,
        constructor: Option<Type>,
        doc: Option<String>,
    },
    Interface {
        visibility: Visibility,
        ty: Type,
        name_span: Span,
        definition: Interface,
        doc: Option<String>,
    },
    Value {
        visibility: Visibility,
        ty: Type,
        name_span: Option<Span>,
        allowed_lints: Vec<String>,
        go_hints: Vec<String>,
        go_name: Option<String>,
        doc: Option<String>,
    },
}

impl Definition {
    pub fn ty(&self) -> &Type {
        match self {
            Definition::TypeAlias { ty, .. } => ty,
            Definition::Enum { ty, .. } => ty,
            Definition::ValueEnum { ty, .. } => ty,
            Definition::Struct { ty, .. } => ty,
            Definition::Interface { ty, .. } => ty,
            Definition::Value { ty, .. } => ty,
        }
    }

    pub fn visibility(&self) -> &Visibility {
        match self {
            Definition::TypeAlias { visibility, .. } => visibility,
            Definition::Enum { visibility, .. } => visibility,
            Definition::ValueEnum { visibility, .. } => visibility,
            Definition::Struct { visibility, .. } => visibility,
            Definition::Interface { visibility, .. } => visibility,
            Definition::Value { visibility, .. } => visibility,
        }
    }

    pub fn allowed_lints(&self) -> &[String] {
        match self {
            Definition::Value { allowed_lints, .. } => allowed_lints,
            _ => &[],
        }
    }

    pub fn go_hints(&self) -> &[String] {
        match self {
            Definition::Value { go_hints, .. } => go_hints,
            _ => &[],
        }
    }

    pub fn go_name(&self) -> Option<&str> {
        match self {
            Definition::Value { go_name, .. } => go_name.as_deref(),
            _ => None,
        }
    }

    pub fn methods_mut(&mut self) -> Option<&mut MethodSignatures> {
        match self {
            Definition::Struct { methods, .. } => Some(methods),
            Definition::TypeAlias { methods, .. } => Some(methods),
            Definition::Enum { methods, .. } => Some(methods),
            Definition::ValueEnum { methods, .. } => Some(methods),
            _ => None,
        }
    }

    pub fn is_type_definition(&self) -> bool {
        matches!(
            self,
            Definition::Struct { .. }
                | Definition::Enum { .. }
                | Definition::ValueEnum { .. }
                | Definition::TypeAlias { .. }
        )
    }

    pub fn name_span(&self) -> Option<Span> {
        match self {
            Definition::TypeAlias { name_span, .. } => Some(*name_span),
            Definition::Enum { name_span, .. } => Some(*name_span),
            Definition::ValueEnum { name_span, .. } => Some(*name_span),
            Definition::Struct { name_span, .. } => Some(*name_span),
            Definition::Interface { name_span, .. } => Some(*name_span),
            Definition::Value { name_span, .. } => *name_span,
        }
    }

    pub fn doc(&self) -> Option<&String> {
        match self {
            Definition::TypeAlias { doc, .. }
            | Definition::Enum { doc, .. }
            | Definition::ValueEnum { doc, .. }
            | Definition::Struct { doc, .. }
            | Definition::Interface { doc, .. }
            | Definition::Value { doc, .. } => doc.as_ref(),
        }
    }
}

pub type MethodSignatures = HashMap<EcoString, Type>;

#[derive(Debug, Clone, PartialEq)]
pub enum Visibility {
    Public,
    Private,
    Local,
}

impl Visibility {
    pub fn is_public(&self) -> bool {
        matches!(self, Visibility::Public)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct Interface {
    pub name: EcoString,
    pub generics: Vec<Generic>,
    pub parents: Vec<Type>,
    pub methods: HashMap<EcoString, Type>,
}