fluidattacks-blends-domain 0.6.1

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
use crate::query::pred_ast;
use crate::syntax::builders::variable_declaration::build_variable_declaration_node;
use crate::syntax::fields::java::{
    constant_declaration, field_declaration, local_variable_declaration, variable_declarator,
};
use crate::syntax::metadata::java::add_instance_to_metadata;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};

fn declaration_parent(args: &SyntaxGraphArgs<'_>, n_id: NodeId) -> Option<NodeId> {
    let parent_id = pred_ast(args.ast_graph, n_id, None).first().copied()?;
    matches!(
        args.ast_graph.label_type(parent_id),
        Some("constant_declaration" | "field_declaration" | "local_variable_declaration")
    )
    .then_some(parent_id)
}

fn registers_instance(args: &SyntaxGraphArgs<'_>, parent_id: NodeId) -> bool {
    matches!(
        args.ast_graph.label_type(parent_id),
        Some("constant_declaration" | "local_variable_declaration")
    ) && args.syntax_graph.nodes.contains_key(&NodeId(0))
}

pub fn reader(
    args: &mut SyntaxGraphArgs<'_>,
    n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
    let name_id = args.required_field_alt(n_id, variable_declarator::NAME)?;
    let var_name = node_to_str(args.ast_graph, name_id);
    let val_id = args.optional_field_alt(n_id, variable_declarator::VALUE);

    let parent_id = declaration_parent(args, n_id);
    let var_type = parent_id
        .and_then(|parent_id| match args.ast_graph.label_type(parent_id) {
            Some("constant_declaration") => args
                .required_field_alt(parent_id, constant_declaration::TYPE)
                .ok(),
            Some("field_declaration") => args
                .required_field_alt(parent_id, field_declaration::TYPE)
                .ok(),
            Some("local_variable_declaration") => args
                .required_field_alt(parent_id, local_variable_declaration::TYPE)
                .ok(),
            _ => None,
        })
        .map(|type_id| node_to_str(args.ast_graph, type_id));

    if let (Some(parent_id), Some(instance_type)) = (parent_id, var_type.as_deref()) {
        if registers_instance(args, parent_id) {
            add_instance_to_metadata(args, instance_type, &var_name, &[])?;
        }
    }

    build_variable_declaration_node(args, n_id, var_name, var_type, val_id, None, None).map(Some)
}