squawk-ide 2.63.0

Linter for Postgres migrations & SQL
Documentation
use rowan::TextSize;
use salsa::Database as Db;
use squawk_linter::Edit;
use squawk_syntax::{
    SyntaxKind,
    ast::{self, AstNode},
};

use crate::{file::InFile, offsets::token_from_offset};

use super::{ActionKind, CodeAction};

pub(super) fn rewrite_system_user_as_function_call(
    db: &dyn Db,
    position: InFile<TextSize>,
    actions: &mut Vec<CodeAction>,
) -> Option<()> {
    let token = token_from_offset(db, position)?;
    if token.kind() != SyntaxKind::SYSTEM_USER_KW {
        return None;
    }

    let name = token.parent().and_then(ast::NameRef::cast)?;
    let parent = name.syntax().parent()?;

    if ast::CallExpr::can_cast(parent.kind()) || ast::FieldExpr::can_cast(parent.kind()) {
        return None;
    }

    actions.push(CodeAction {
        title: "Rewrite as function call `pg_catalog.system_user()`".to_owned(),
        edits: vec![Edit::replace(
            name.syntax().text_range(),
            "pg_catalog.system_user()",
        )],
        kind: ActionKind::RefactorRewrite,
    });

    Some(())
}

#[cfg(test)]
mod test {
    use insta::assert_snapshot;

    use crate::code_actions::test_utils::{apply_code_action, code_action_not_applicable};

    use super::rewrite_system_user_as_function_call;

    #[test]
    fn rewrites_system_user_as_function_call() {
        assert_snapshot!(
            apply_code_action(
                rewrite_system_user_as_function_call,
                "select SYSTEM_$0USER;",
            ),
            @"select pg_catalog.system_user();"
        );
    }

    #[test]
    fn rewrites_at_expression_boundary() {
        assert_snapshot!(
            apply_code_action(
                rewrite_system_user_as_function_call,
                "select (SYSTEM_USER$0)::text;",
            ),
            @"select (pg_catalog.system_user())::text;"
        );
    }

    #[test]
    fn not_applicable_to_function_call() {
        assert!(code_action_not_applicable(
            rewrite_system_user_as_function_call,
            "select system_$0user();"
        ));
    }

    #[test]
    fn not_applicable_to_qualified_reference() {
        assert!(code_action_not_applicable(
            rewrite_system_user_as_function_call,
            "select account.system_$0user from accounts;"
        ));
    }
}