teo-parser 0.3.0

Parser for Teo schema language
Documentation
use maplit::btreemap;
use crate::ast::include_handler_from_template::{IncludeHandlerFromTemplate, IncludeHandlerFromTemplateResolved};
use crate::ast::model::Model;
use crate::ast::reference_space::ReferenceSpace;
use crate::availability::Availability;
use crate::r#type::keyword::Keyword;
use crate::r#type::reference::Reference;
use crate::r#type::Type;
use crate::resolver::resolve_decorator::resolve_decorator;
use crate::resolver::resolve_identifier::{resolve_identifier_path_names_with_filter_to_top};
use crate::resolver::resolver_context::ResolverContext;
use crate::traits::node_trait::NodeTrait;
use crate::traits::resolved::Resolve;
use crate::utils::top_filter::{top_filter_for_handler_template};

pub(super) fn resolve_include_handler_from_template_decorators<'a>(
    include_handler_from_template: &'a IncludeHandlerFromTemplate,
    context: &'a ResolverContext<'a>,
    model: &'a Model,
) {
    if context.has_examined_default_path(&include_handler_from_template.string_path, Availability::default()) {
        context.insert_duplicated_identifier(include_handler_from_template.identifier_path().span);
    }
    context.add_examined_default_path(include_handler_from_template.string_path.clone(), Availability::default());
    let template_path = include_handler_from_template.identifier_path();
    if let Some(template_node) = resolve_identifier_path_names_with_filter_to_top(
        &template_path.names(),
        context.schema,
        context.source(),
        &context.current_namespace_path(),
        &top_filter_for_handler_template(),
        context.current_availability()
    ) {
        let template = template_node.as_handler_template_declaration().unwrap();
        let mut resolved = IncludeHandlerFromTemplateResolved {
            input_type: None,
            output_type: Type::Any,
            template_path: template.string_path.clone(),
        };
        if let Some(template_input_type_expr) = template.input_type() {
            let input_type = template_input_type_expr.resolved();
            resolved.input_type = Some(type_replace_generics_for_handler_template_type(input_type, model));
        }
        let output_type = template.output_type().resolved();
        resolved.output_type = type_replace_generics_for_handler_template_type(output_type, model);
        include_handler_from_template.resolve(resolved);
        let mut keywords_map = btreemap!{};
        keywords_map.insert(Keyword::SelfIdentifier, Type::ModelObject(Reference::new(model.path.clone(), model.string_path.clone())));
        for decorator in include_handler_from_template.decorators() {
            resolve_decorator(decorator, context, &keywords_map, ReferenceSpace::HandlerDecorator);
        }
    } else {
        context.insert_diagnostics_error(include_handler_from_template.identifier_path().span(), "handler template definition is not found");
    }
}

fn type_replace_generics_for_handler_template_type(original: &Type, model: &Model) -> Type {
    original.replace_keywords(&btreemap! {
        Keyword::SelfIdentifier => Type::ModelObject(Reference::new(model.path.clone(), model.string_path.clone())),
    })
}