teo-parser 0.3.0

Parser for Teo schema language
Documentation
use maplit::btreemap;
use crate::ast::constant_declaration::{ConstantDeclaration};
use crate::expr::ExprInfo;
use crate::r#type::r#type::Type;
use crate::resolver::resolve_expression::resolve_expression;
use crate::resolver::resolve_type_expr::resolve_type_expr;
use crate::resolver::resolver_context::ResolverContext;
use crate::traits::node_trait::NodeTrait;
use crate::traits::resolved::Resolve;

pub(super) fn resolve_constant_references<'a>(constant: &'a ConstantDeclaration, context: &'a ResolverContext<'a>) {
    if constant.is_resolved() { return; }
    *constant.actual_availability.borrow_mut() = context.current_availability();
    if let Some(type_expr) = constant.type_expr() {
        resolve_type_expr(type_expr, &vec![], &vec![], &btreemap!{}, context, context.current_availability());
    }
    let undetermined = Type::Undetermined;
    context.push_dependency(constant.path.clone());
    let resolved = resolve_expression(constant.expression(), context, constant.type_expr().map_or(&undetermined, |t| t.resolved()), &btreemap! {});
    if let Some(type_expr) = constant.type_expr() {
        if type_expr.resolved().test(resolved.r#type()) {
            constant.resolve(ExprInfo {
                r#type: type_expr.resolved().clone(),
                value: resolved.value().cloned(),
                reference_info: resolved.reference_info().cloned(),
            });
        } else {
            if resolved.r#type().can_coerce_to(type_expr.resolved(), context.schema) {
                constant.resolve(ExprInfo {
                    r#type: type_expr.resolved().clone(),
                    value: if let Some(value) = resolved.value() {
                        resolved.r#type().coerce_value_to(value, type_expr.resolved())
                    } else {
                        None
                    },
                    reference_info: resolved.reference_info().cloned(),
                });
            } else {
                context.insert_diagnostics_error(constant.expression().span(), format!("expect {}, found {}", type_expr.resolved(), resolved.r#type()));
                constant.resolve(resolved.type_altered(type_expr.resolved().clone()));
            }
        }
    } else {
        constant.resolve(resolved);
    }
    context.pop_dependency();
}

pub(super) fn resolve_constant_check<'a>(constant: &'a ConstantDeclaration, context: &'a ResolverContext<'a>) {
    if constant.use_count.get() == 0 {
        context.insert_diagnostics_warning(constant.identifier().span(), "unused constant");
    }
}