fluidattacks-blends-domain 0.6.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
use alloc::borrow::ToOwned;
use alloc::format;
use alloc::string::String;

use crate::query::{get_node_by_path, label_text};
use crate::syntax::builders::class_declaration::build_class_node;
use crate::syntax::fields::java::{class_declaration, record_declaration};
use crate::syntax::metadata::java::add_class_to_metadata;
use crate::syntax::readers::java::common::extract_modifiers;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};

fn inherited_class(args: &SyntaxGraphArgs<'_>, n_id: NodeId) -> Option<String> {
    let graph = args.ast_graph;
    let extends = get_node_by_path(graph, n_id, &["superclass", "type_identifier"])
        .and_then(|extends_id| label_text(graph, extends_id))
        .map(ToOwned::to_owned);
    let implements = get_node_by_path(
        graph,
        n_id,
        &["super_interfaces", "type_list", "type_identifier"],
    )
    .and_then(|implements_id| label_text(graph, implements_id))
    .filter(|value| !value.is_empty());

    match (extends, implements) {
        (Some(extends), Some(implements)) => Some(format!("{extends},{implements}")),
        (Some(extends), None) => Some(extends),
        (None, Some(implements)) => Some(implements.to_owned()),
        (None, None) => None,
    }
}

pub fn reader(
    args: &mut SyntaxGraphArgs<'_>,
    n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
    let (name_id, block_id, parameters_id) = match args.ast_graph.label_type(n_id) {
        Some("record_declaration") => (
            args.required_field_alt(n_id, record_declaration::NAME)?,
            args.required_field_alt(n_id, record_declaration::BODY)?,
            Some(args.required_field_alt(n_id, record_declaration::PARAMETERS)?),
        ),
        Some("class_declaration") => (
            args.required_field_alt(n_id, class_declaration::NAME)?,
            args.required_field_alt(n_id, class_declaration::BODY)?,
            None,
        ),
        _ => return Err(SyntaxGraphError::UnexpectedAstShape),
    };
    let name = node_to_str(args.ast_graph, name_id);
    let inherited = inherited_class(args, n_id);

    let attr_list_ids: &[NodeId] = match &parameters_id {
        Some(id) => core::slice::from_ref(id),
        None => &[],
    };

    if args.syntax_graph.nodes.contains_key(&NodeId(0)) {
        add_class_to_metadata(args, n_id, &name)?;
    }

    let (modifiers_id, access_modifiers) = extract_modifiers(args.ast_graph, n_id);
    build_class_node(
        args,
        n_id,
        name,
        Some(block_id),
        attr_list_ids,
        inherited,
        modifiers_id,
        access_modifiers,
    )
    .map(Some)
}