Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be170715 authored by Martin Geisler's avatar Martin Geisler Committed by Cherrypicker Worker
Browse files

pdl: Extract constraint_to_value helper

Tag: #refactor
Bug: 228306436
Test: atest pdl_tests pdl_rust_generator_tests_{le,be}
(cherry picked from https://android-review.googlesource.com/q/commit:40e4b773f071c8e2f0a7cd52d3289c99dc0e2b6f)
Merged-In: Ibfe35033934ea83a665663e92bf37504d3c33406
Change-Id: Ibfe35033934ea83a665663e92bf37504d3c33406
parent fdd097d3
Loading
Loading
Loading
Loading
+26 −20
Original line number Diff line number Diff line
@@ -170,6 +170,31 @@ fn find_constrained_parent_fields<'a>(
    })
}

/// Turn the constraint into a value (such as `10` or
/// `SomeEnum::Foo`).
pub fn constraint_to_value(
    packet_scope: &lint::PacketScope<'_>,
    constraint: &ast::Constraint,
) -> proc_macro2::TokenStream {
    match constraint {
        ast::Constraint { value: Some(value), .. } => {
            let value = proc_macro2::Literal::usize_unsuffixed(*value);
            quote!(#value)
        }
        // TODO(mgeisler): include type_id in `ast::Constraint` and
        // drop the packet_scope argument.
        ast::Constraint { tag_id: Some(tag_id), .. } => {
            let type_id = match &packet_scope.all_fields[&constraint.id].desc {
                ast::FieldDesc::Typedef { type_id, .. } => format_ident!("{type_id}"),
                _ => unreachable!("Invalid constraint: {constraint:?}"),
            };
            let tag_id = format_ident!("{}", tag_id.to_upper_camel_case());
            quote!(#type_id::#tag_id)
        }
        _ => unreachable!("Invalid constraint: {constraint:?}"),
    }
}

/// Generate code for `ast::Decl::Packet` and `ast::Decl::Struct`
/// values.
fn generate_packet_decl(
@@ -287,26 +312,7 @@ fn generate_packet_decl(
        let mut value = named_fields
            .iter()
            .map(|&id| match packet_scope.all_constraints.get(id) {
                Some(constraint) => {
                    let value = match constraint {
                        ast::Constraint { value: Some(value), .. } => {
                            let value = proc_macro2::Literal::usize_unsuffixed(*value);
                            quote!(#value)
                        }
                        ast::Constraint { tag_id: Some(tag_id), .. } => {
                            let type_id = match packet_scope.all_fields.get(id).map(|f| &f.desc) {
                                Some(ast::FieldDesc::Typedef { type_id, .. }) => {
                                    format_ident!("{type_id}")
                                }
                                _ => unreachable!("Invalid constraint: {constraint:?}"),
                            };
                            let tag_id = format_ident!("{}", tag_id.to_upper_camel_case());
                            quote!(#type_id::#tag_id)
                        }
                        _ => unreachable!("Invalid constraint: {constraint:?}"),
                    };
                    quote!(#value)
                }
                Some(constraint) => constraint_to_value(packet_scope, constraint),
                None => {
                    let id = format_ident!("{id}");
                    quote!(self.#id)
+7 −20
Original line number Diff line number Diff line
use crate::backends::rust::{find_constrained_parent_fields, mask_bits, types};
use crate::backends::rust::{
    constraint_to_value, find_constrained_parent_fields, mask_bits, types,
};
use crate::parser::ast as parser_ast;
use crate::{ast, lint};
use heck::ToUpperCamelCase;
@@ -571,26 +573,11 @@ impl<'a> FieldParser<'a> {
                ast::DeclDesc::Packet { id, constraints, .. }
                | ast::DeclDesc::Struct { id, constraints, .. } => {
                    for constraint in constraints.iter() {
                        let value = match constraint {
                            ast::Constraint { value: Some(value), .. } => {
                                let value = proc_macro2::Literal::usize_unsuffixed(*value);
                                quote!(#value)
                            }
                            ast::Constraint { id, tag_id: Some(tag_id), .. } => {
                                // TODO: add `type_id` to `Constraint`.
                                let type_id = match &packet_scope.all_fields[id].desc {
                                    ast::FieldDesc::Typedef { type_id, .. } => {
                                        format_ident!("{type_id}")
                                    }
                                    _ => unreachable!("Invalid constraint: {constraint:?}"),
                                };
                                let tag_id = format_ident!("{}", tag_id.to_upper_camel_case());
                                quote!(#type_id::#tag_id)
                            }
                            _ => unreachable!("Invalid constraint: {constraint:?}"),
                        };
                        constrained_fields.insert(&constraint.id);
                        constraint_values.insert((id.as_str(), &constraint.id), value);
                        constraint_values.insert(
                            (id.as_str(), &constraint.id),
                            constraint_to_value(packet_scope, constraint),
                        );
                    }
                }
                _ => unreachable!("Invalid child: {child:?}"),