#[allow(unused)]
use log::info;
use ropey::Rope;
use tower_lsp::lsp_types::*;
use vhdl_lang::Project;

use crate::{sources::LSPSupport, utils::is_character_ordered_match};

/// cleanup the text of a definition so it can be included in completions
pub fn clean_type_str(type_str: &str, ident: &str) -> String {
    let endings: &[_] = &[';', ','];
    // remove anything after an equals sign
    let eq_offset = type_str.find('=').unwrap_or(type_str.len());
    let mut result = type_str.to_string();
    result.replace_range(eq_offset.., "");
    result
        .trim_start()
        .trim_end()
        .trim_end_matches(endings)
        .trim_end_matches(ident)
        .split_whitespace()
        .collect::<Vec<&str>>()
        .join(" ")
        .replace("[ ", "[")
        .replace(" ]", "]")
        .replace(" : ", ":")
}

pub fn copy_defs(defs: &[Box<dyn Definition>]) -> Vec<Box<dyn Definition>> {
    let mut decs: Vec<Box<dyn Definition>> = Vec::new();
    for def in defs {
        decs.push(Box::new(GenericDec {
            ident: def.ident(),
            byte_idx: def.byte_idx(),
            url: def.url(),
            type_str: def.type_str(),
            completion_kind: def.completion_kind(),
            symbol_kind: def.symbol_kind(),
            def_type: def.def_type(),
        }))
    }
    decs
}

pub fn copy_scopes(scopes: &[Box<dyn Scope>]) -> Vec<Box<dyn Scope>> {
    let mut scope_decs: Vec<Box<dyn Scope>> = Vec::new();
    for scope in scopes {
        let mut scope_copy = GenericScope {
            ident: scope.ident(),
            byte_idx: scope.byte_idx(),
            start: scope.start(),
            end: scope.end(),
            url: scope.url(),
            type_str: scope.type_str(),
            completion_kind: scope.completion_kind(),
            symbol_kind: scope.symbol_kind(),
            def_type: scope.def_type(),
            defs: Vec::new(),
            scopes: Vec::new(),
        };
        scope_copy.defs.extend(copy_defs(scope.defs()));
        scope_copy.scopes.extend(copy_scopes(scope.scopes()));
        scope_decs.push(Box::new(scope_copy))
    }
    scope_decs
}

/// Definition 是所有非 scope 类型 symbol 的父类
pub trait Definition: std::fmt::Debug + Sync + Send {
    /// symbol 或者 scope 的名字，identity 的缩写
    /// 
    /// 对于 definition，而言 ident 就是它的字面量，比如
    /// ```verilog
    /// parameter wire_size = 12;
    /// ```
    /// 上面的 `wire_size` 这个 symbol 的 name 就是 `wire_size`
    /// 
    /// 对于 scope 而言
    /// ```verilog
    /// module beginner();
    ///     adwadwa
    /// endmodule
    /// 上面这个 module scope 的 ident 就是 `beginner`
    /// ```
    fn ident(&self) -> String;
    /// 相对于文本的偏移量，可以利用 Rope 的 `byte_to_pos` 函数转换成 Position
    fn byte_idx(&self) -> usize;
    /// 当前 symbol 所在文件的 url
    fn url(&self) -> Url;
    /// 输出 Definition 的字符
    fn type_str(&self) -> String;
    /// 类别，用于自动补全
    fn completion_kind(&self) -> CompletionItemKind;
    /// 类别，用于文件大纲
    fn symbol_kind(&self) -> SymbolKind;
    /// 类别，内部使用
    fn def_type(&self) -> DefinitionType;
    /// 等价于 self.ident.starts_with
    fn starts_with(&self, token: &str) -> bool;
    /// 构造 completion 的 item
    fn completion(&self) -> CompletionItem;
}

/// Scope 是所有 scope 类型 symbol 的父类
pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
    // the start byte of this scope
    fn start(&self) -> usize;
    // the end byte of this scope
    fn end(&self) -> usize;
    // all the within this scope
    fn defs(&self) -> &Vec<Box<dyn Definition>>;
    // all the scopes within this scope, ex. task inside a module
    fn scopes(&self) -> &Vec<Box<dyn Scope>>;
    // the definition of this scope
    fn definition(&self) -> GenericDec {
        GenericDec {
            ident: self.ident(),
            byte_idx: self.byte_idx(),
            url: self.url(),
            type_str: self.type_str(),
            completion_kind: self.completion_kind(),
            symbol_kind: self.symbol_kind(),
            def_type: DefinitionType::GenericScope,
        }
    }
    /// return a completion from the scope tree, this function should be called on the global scope
    fn get_completion(&self, token: &str, byte_idx: usize, url: &Url) -> Vec<CompletionItem> {
        let mut completions: Vec<CompletionItem> = Vec::new();
        // first we need to go down the scope tree, to the scope the user is invoking a completion
        // in
        for scope in self.scopes() {
            // 如果当前的 token 在这个 scope 中，那么需要递归获取这个 scope 中的所有补全项目
            if &scope.url() == url && scope.start() <= byte_idx && byte_idx <= scope.end() {
                completions = scope.get_completion(token, byte_idx, url);
                break;
            }
        }

        // let completion_idents: Vec<String> = completions.iter().map(|x| x.label.clone()).collect();
        
        // 寻找前缀相同的 symbol
        // 这里面并没有 macro
        for symbol in self.defs() {
            // 此处的去重会在外部完成
            let symbol_name = symbol.ident();
            // 此处仍然会给出 module 的补全，但是此处的只是名字的补全，而不是自动例化
            match &symbol.def_type() {
                DefinitionType::Port => {},
                DefinitionType::Net => {},
                DefinitionType::Macro => {
                    // 对于 TextMacro 类型的，因为是全局属性的，不进行补全
                    // 对于它的补全请参考 vlog_directives_completion & vlog_directives_completion_without_prefix
                    continue;
                },
                DefinitionType::Data => {},
                DefinitionType::Modport => {},
                DefinitionType::Subroutine => {},
                DefinitionType::ModuleInstantiation => {},
                DefinitionType::GenericScope => {},
                DefinitionType::Class => {},
            };
            if is_character_ordered_match(token, &symbol_name) {
                completions.push(symbol.completion());
            }
        }
        // 寻找前缀相同的 scope
        for scope in self.scopes() {
            if scope.starts_with(token) {
                completions.push(scope.completion());
            }
        }
        completions
    }


    /// 根据输入的 token，计算出这个 token 在 scope 中的定义
    /// 比如输入 clock，则返回 clock 这个变量在哪里被定义，没有则返回 None
    /// - `token`: 需要查找定义的完整的单词
    /// - `byte_idx`: 当前光标所在文档的偏移量
    /// - `url`: 当前文档的 url
    fn get_definition(&self, token: &str, byte_idx: usize, url: &Url) -> Option<GenericDec> {
        let mut definition: Option<GenericDec> = None;

        // 递归进入最浅层的
        for scope in self.scopes() {
            if &scope.url() == url && scope.start() <= byte_idx && byte_idx <= scope.end() {
                definition = scope.get_definition(token, byte_idx, url);
                break;
            }
        }

        if definition.is_none() {
            // 优先找 定义，再找 scope
            for def in self.defs() {
                if def.ident() == token {
                    return Some(GenericDec {
                        ident: def.ident(),
                        byte_idx: def.byte_idx(),
                        url: def.url(),
                        type_str: def.type_str(),
                        completion_kind: def.completion_kind(),
                        symbol_kind: def.symbol_kind(),
                        def_type: def.def_type(),
                    });
                }
            }
            for scope in self.scopes() {
                if scope.ident() == token {
                    return Some(scope.definition());
                }
            }
        }
        definition
    }


    /// returns all symbols in a document
    fn document_symbols(&self, uri: &Url, doc: &Rope) -> Vec<DocumentSymbol> {
        let mut symbols: Vec<DocumentSymbol> = Vec::new();
        for scope in self.scopes() {
            if &scope.url() == uri {
                #[allow(deprecated)]
                symbols.push(DocumentSymbol {
                    name: scope.ident(),
                    detail: Some(scope.type_str()),
                    kind: scope.symbol_kind(),
                    deprecated: None,
                    range: Range::new(doc.byte_to_pos(scope.start()), doc.byte_to_pos(scope.end())),
                    selection_range: Range::new(
                        doc.byte_to_pos(scope.byte_idx()),
                        doc.byte_to_pos(scope.byte_idx() + scope.ident().len()),
                    ),
                    children: Some(scope.document_symbols(uri, doc)),
                    tags: None,
                })
            }
        }
        for def in self.defs() {
            #[allow(deprecated)]
            symbols.push(DocumentSymbol {
                name: def.ident(),
                detail: Some(def.type_str()),
                kind: def.symbol_kind(),
                deprecated: None,
                range: Range::new(
                    doc.byte_to_pos(def.byte_idx()),
                    doc.byte_to_pos(def.byte_idx() + def.ident().len()),
                ),
                selection_range: Range::new(
                    doc.byte_to_pos(def.byte_idx()),
                    doc.byte_to_pos(def.byte_idx() + def.ident().len()),
                ),
                children: None,
                tags: None,
            })
        }
        symbols
    }

    /// highlight all references of a symbol
    fn document_highlights(
        &self,
        uri: &Url,
        doc: &Rope,
        // all references in the doc's syntax tree
        references: Vec<(String, usize)>,
        // byte_idx of symbol definition
        byte_idx: usize,
    ) -> Vec<DocumentHighlight> {
        // to find references we need to grab references from locations downward from the
        // definition
        for scope in self.scopes() {
            if &scope.url() == uri && scope.start() <= byte_idx && byte_idx <= scope.end() {
                return scope.document_highlights(uri, doc, references, byte_idx);
            }
        }
        // we should now be in the scope of the definition, so we can grab all references
        // in this scope. This also grabs references below this scope.
        references
            .iter()
            .filter(|x| self.start() <= x.1 && x.1 <= self.end())
            .map(|x| DocumentHighlight {
                range: Range::new(doc.byte_to_pos(x.1), doc.byte_to_pos(x.1 + x.0.len())),
                kind: None,
            })
            .collect()
    }
}

#[derive(Debug, Clone, Copy)]
pub enum DefinitionType {
    Port,
    Net,
    Macro,
    Data,
    Modport,
    Subroutine,
    ModuleInstantiation,
    GenericScope,
    Class,
}

#[derive(Debug)]
pub struct PortDec {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub interface: Option<String>,
    pub modport: Option<String>,
}

impl PortDec {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            type_str: String::new(),
            completion_kind: CompletionItemKind::PROPERTY,
            symbol_kind: SymbolKind::PROPERTY,
            def_type: DefinitionType::Port,
            interface: None,
            modport: None,
            url: url.clone(),
        }
    }
}

impl Definition for PortDec {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        let label_details = CompletionItemLabelDetails {
            description: Some("module port".to_string()),
            ..Default::default()
        };
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            label_details: Some(label_details),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

#[derive(Debug)]
pub struct GenericDec {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
}

impl GenericDec {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::VARIABLE,
            // FIXME: check if this replacement is correct
            symbol_kind: SymbolKind::NULL,
            def_type: DefinitionType::Net,
        }
    }
}

impl Definition for GenericDec {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

#[derive(Debug)]
pub struct PackageImport {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub asterisk: bool,
    pub import_ident: Option<String>,
}

impl PackageImport {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::TEXT,
            symbol_kind: SymbolKind::NAMESPACE,
            def_type: DefinitionType::Data,
            asterisk: false,
            import_ident: None,
        }
    }
}

impl Definition for PackageImport {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident.clone())),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

#[derive(Debug)]
pub struct SubDec {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub start: usize,
    pub end: usize,
    pub defs: Vec<Box<dyn Definition>>,
    pub scopes: Vec<Box<dyn Scope>>,
}

impl SubDec {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::FUNCTION,
            symbol_kind: SymbolKind::FUNCTION,
            def_type: DefinitionType::Subroutine,
            start: 0,
            end: 0,
            defs: Vec::new(),
            scopes: Vec::new(),
        }
    }
}

impl Definition for SubDec {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

impl Scope for SubDec {
    fn start(&self) -> usize {
        self.start
    }

    fn end(&self) -> usize {
        self.end
    }
    fn defs(&self) -> &Vec<Box<dyn Definition>> {
        &self.defs
    }

    fn scopes(&self) -> &Vec<Box<dyn Scope>> {
        &self.scopes
    }
}

#[derive(Debug)]
pub struct ModportDec {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub ports: Vec<Box<dyn Definition>>,
}

impl ModportDec {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::INTERFACE,
            symbol_kind: SymbolKind::INTERFACE,
            def_type: DefinitionType::Modport,
            ports: Vec::new(),
        }
    }
}

impl Definition for ModportDec {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

#[derive(Debug)]
pub struct ModInst {
    pub ident: String,
    pub byte_idx: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub mod_ident: String,
}

impl ModInst {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::MODULE,
            symbol_kind: SymbolKind::MODULE,
            def_type: DefinitionType::ModuleInstantiation,
            mod_ident: String::new(),
        }
    }
}

impl Definition for ModInst {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

pub struct VhdlProject {
    pub project: Project,
    pub std_config: vhdl_lang::Config,
    pub config_file_strs: Vec<String>
}

#[derive(Debug)]
pub struct GenericScope {
    pub ident: String,
    pub byte_idx: usize,
    pub start: usize,
    pub end: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub defs: Vec<Box<dyn Definition>>,
    pub scopes: Vec<Box<dyn Scope>>,
}

impl GenericScope {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            start: 0,
            end: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::MODULE,
            symbol_kind: SymbolKind::MODULE,
            def_type: DefinitionType::GenericScope,
            defs: Vec::new(),
            scopes: Vec::new(),
        }
    }
}

impl Definition for GenericScope {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

impl Scope for GenericScope {
    fn start(&self) -> usize {
        self.start
    }

    fn end(&self) -> usize {
        self.end
    }

    fn defs(&self) -> &Vec<Box<dyn Definition>> {
        &self.defs
    }

    fn scopes(&self) -> &Vec<Box<dyn Scope>> {
        &self.scopes
    }
}

#[derive(Debug)]
pub struct ClassDec {
    pub ident: String,
    pub byte_idx: usize,
    pub start: usize,
    pub end: usize,
    pub url: Url,
    pub type_str: String,
    pub completion_kind: CompletionItemKind,
    pub symbol_kind: SymbolKind,
    pub def_type: DefinitionType,
    pub defs: Vec<Box<dyn Definition>>,
    pub scopes: Vec<Box<dyn Scope>>,
    // class, package
    pub extends: (Vec<String>, Option<String>),
    // class, package
    pub implements: Vec<(String, Option<String>)>,
}

impl ClassDec {
    pub fn new(url: &Url) -> Self {
        Self {
            ident: String::new(),
            byte_idx: 0,
            start: 0,
            end: 0,
            url: url.clone(),
            type_str: String::new(),
            completion_kind: CompletionItemKind::CLASS,
            symbol_kind: SymbolKind::CLASS,
            def_type: DefinitionType::Class,
            defs: Vec::new(),
            scopes: Vec::new(),
            extends: (Vec::new(), None),
            implements: Vec::new(),
        }
    }
}

impl Definition for ClassDec {
    fn ident(&self) -> String {
        self.ident.clone()
    }
    fn byte_idx(&self) -> usize {
        self.byte_idx
    }
    fn url(&self) -> Url {
        self.url.clone()
    }
    fn type_str(&self) -> String {
        self.type_str.clone()
    }
    fn completion_kind(&self) -> CompletionItemKind {
        self.completion_kind
    }
    fn symbol_kind(&self) -> SymbolKind {
        self.symbol_kind
    }
    fn def_type(&self) -> DefinitionType {
        self.def_type
    }
    fn starts_with(&self, token: &str) -> bool {
        self.ident.starts_with(token)
    }
    fn completion(&self) -> CompletionItem {
        CompletionItem {
            label: self.ident.clone(),
            detail: Some(clean_type_str(&self.type_str, &self.ident)),
            kind: Some(self.completion_kind),
            ..CompletionItem::default()
        }
    }
}

impl Scope for ClassDec {
    fn start(&self) -> usize {
        self.start
    }

    fn end(&self) -> usize {
        self.end
    }

    fn defs(&self) -> &Vec<Box<dyn Definition>> {
        &self.defs
    }

    fn scopes(&self) -> &Vec<Box<dyn Scope>> {
        &self.scopes
    }
}
