harn-lint 0.10.78

Linter for the Harn programming language
Documentation
use harn_lexer::Span;
use harn_parser::{DiagnosticCode as Code, Node, SNode};

use super::Linter;
use crate::diagnostic::{LintDiagnostic, LintSeverity};

impl Linter<'_> {
    pub(super) fn check_harness_method_effect_policy(
        &mut self,
        object: &SNode,
        method: &str,
        args: &[SNode],
        span: Span,
    ) {
        let connector_denial =
            self.connector_effect_export_stack
                .last()
                .cloned()
                .and_then(|export| {
                    let harness_name = self.harness_binding_name()?;
                    let capability = match &object.node {
                        Node::PropertyAccess {
                            object: root,
                            property,
                        }
                        | Node::OptionalPropertyAccess {
                            object: root,
                            property,
                        } if matches!(
                            &root.node,
                            Node::Identifier(name) if name == harness_name
                        ) =>
                        {
                            property.clone()
                        }
                        _ => return None,
                    };
                    harn_vm::connector_export_denied_harness_method_reason(
                        &export,
                        &capability,
                        method,
                    )
                    .map(|reason| (export, capability, reason))
                });

        if let Some((export, capability, reason)) = connector_denial {
            self.diagnostics.push(LintDiagnostic {
                code: Code::LintConnectorEffectPolicy,
                rule: "connector-effect-policy".into(),
                message: format!(
                    "connector export `{export}` calls disallowed capability \
                     `harness.{capability}.{method}`: {reason}"
                ),
                span,
                severity: LintSeverity::Warning,
                suggestion: Some(format!(
                    "move `harness.{capability}.{method}` out of `{export}` or configure \
                     a trusted connector effect-policy override"
                )),
                fix: None,
            });
        }

        self.check_redundant_clone_args(method, args);
    }
}