loalang 0.1.15

Loa is a general-purpose, purely immutable, object-oriented programming language.
Documentation
use crate::server_handler::*;

pub struct HoverRequestHandler;
impl RequestHandler for HoverRequestHandler {
    type R = request::HoverRequest;

    fn handle(context: &mut ServerContext, params: TextDocumentPositionParams) -> Option<Hover> {
        let (uri, location) = convert::from_lsp::position_params(params);
        let location = context.server.location(&uri, location)?;

        if let Some(expression) = context.server.literal_expression_at(location.clone()) {
            let type_ = context
                .server
                .analysis
                .types
                .get_type_of_expression(&expression);

            return Some(Hover {
                range: Some(convert::from_loa::span_to_range(expression.span)),
                contents: HoverContents::Markup(MarkupContent {
                    kind: MarkupKind::Markdown,
                    value: type_.to_markdown(&context.server.analysis.navigator),
                }),
            });
        }

        let usage = context.server.usage(location.clone())?;

        let markdown = if usage.handle.node.is_message() {
            let behaviour = context.server.behaviour_at(location)?;
            behaviour
                .with_applied_message(
                    &usage.handle.node,
                    &context.server.analysis.navigator,
                    &context.server.analysis.types,
                )
                .to_markdown(&context.server.analysis.navigator)
        } else if usage.declaration.node.is_method() {
            let behaviour = context.server.behaviour_at(location)?;
            behaviour.to_markdown(&context.server.analysis.navigator)
        } else {
            let type_ = context.server.type_at(location);

            if let semantics::Type::Unknown = type_ {
                return None;
            }

            type_.to_markdown(&context.server.analysis.navigator)
        };
        Some(Hover {
            range: Some(convert::from_loa::span_to_range(usage.handle.node.span)),
            contents: HoverContents::Markup(MarkupContent {
                kind: MarkupKind::Markdown,
                value: markdown,
            }),
        })
    }
}