Skip to content

Commit

Permalink
Add VintfStability annotation support and passed the related test cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff Kim committed Oct 1, 2024
1 parent af692fd commit 4c1de1d
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 68 deletions.
71 changes: 62 additions & 9 deletions rsbinder-aidl/src/const_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,52 @@ macro_rules! arithmetic_basic_op {
}
}

#[derive(Debug, Clone)]
pub(crate) struct InitParam {
pub is_const: bool,
pub is_fixed_array: bool,
pub is_nullable: bool,
pub is_vintf: bool,
pub crate_name: String,
}

impl InitParam {
pub(crate) fn builder() -> Self {
Self {
is_const: false,
is_fixed_array: false,
is_nullable: false,
is_vintf: false,
crate_name: "rsbinder".into(),
}
}

pub(crate) fn with_const(mut self, is_const: bool) -> Self {
self.is_const = is_const;
self
}

pub(crate) fn with_fixed_array(mut self, is_fixed_array: bool) -> Self {
self.is_fixed_array = is_fixed_array;
self
}

pub(crate) fn with_nullable(mut self, is_nullable: bool) -> Self {
self.is_nullable = is_nullable;
self
}

pub(crate) fn with_vintf(mut self, is_vintf: bool) -> Self {
self.is_vintf = is_vintf;
self
}

pub(crate) fn with_crate_name(mut self, crate_name: &str) -> Self {
self.crate_name = crate_name.to_owned();
self
}
}

#[derive(Default, Debug, Clone)]
pub enum ValueType {
#[default] Void,
Expand Down Expand Up @@ -280,10 +326,10 @@ impl ValueType {
}
}

pub fn to_init(&self, is_const: bool, is_fixed_array: bool, is_nullable: bool) -> String {
pub(crate) fn to_init(&self, param: InitParam) -> String {
match self {
ValueType::String(_) => {
if is_const {
if param.is_const {
format!("\"{}\"", self.to_value_string())
} else {
format!("\"{}\".into()", self.to_value_string())
Expand All @@ -294,13 +340,13 @@ impl ValueType {
ValueType::Char(_) => format!("'{}' as u16", self.to_value_string()),
ValueType::Name(_) => self.to_value_string(),
ValueType::Array(v) => {
let mut res = if is_fixed_array { "[".to_owned() } else { "vec![".to_owned() };
let mut res = if param.is_fixed_array { "[".to_owned() } else { "vec![".to_owned() };
for v in v {
let init_str = v.value.to_init(is_const, is_fixed_array, is_nullable);
let init_str = v.value.to_init(param.clone());

let some_str = if let ValueType::Array(_) = v.value {
init_str
} else if is_nullable {
} else if param.is_nullable {
format!("Some({})", init_str)
} else {
init_str
Expand All @@ -313,13 +359,20 @@ impl ValueType {

res
}
// ValueType::Holder => {
// "rsbinder::ParcelableHolder::new(rsbinder::Stability::Local)".to_owned()
// }
ValueType::Holder => {
println!("Init Holder: {:?}", param);
if param.is_vintf {
format!("{}::ParcelableHolder::new({}::Stability::Vintf)", param.crate_name, param.crate_name)
} else {
"Default::default()".to_string()
}
}
ValueType::Byte(_) | ValueType::Int32(_) | ValueType::Int64(_) | ValueType::Bool(_) |
ValueType::Expr{ .. } | ValueType::Unary{ .. } => self.to_value_string(),

_ => "Default::default()".to_string(),
_ => {
"Default::default()".to_string()
}
}
}

Expand Down
65 changes: 52 additions & 13 deletions rsbinder-aidl/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tera::Tera;

use crate::{parser, add_indent, Namespace};
use crate::parser::Direction;
use crate::const_expr::{ConstExpr, InitParam, ValueType};

const ENUM_TEMPLATE: &str = r##"
pub mod {{mod}} {
Expand Down Expand Up @@ -77,6 +78,9 @@ pub mod {{mod}} {
{{crate}}::impl_deserialize_for_parcelable!(r#{{union_name}});
impl {{crate}}::ParcelableMetadata for r#{{union_name}} {
fn descriptor() -> &'static str { "{{ namespace }}" }
{%- if is_vintf %}
fn stability(&self) -> {{crate}}::Stability { {{crate}}::Stability::Vintf }
{%- endif %}
}
{{crate}}::declare_binder_enum! {
Tag : [i32; {{ members|length }}] {
Expand Down Expand Up @@ -136,6 +140,9 @@ pub mod {{mod}} {
{{crate}}::impl_deserialize_for_parcelable!({{name}});
impl {{crate}}::ParcelableMetadata for {{name}} {
fn descriptor() -> &'static str { "{{namespace}}" }
{%- if is_vintf %}
fn stability(&self) -> {{crate}}::Stability { {{crate}}::Stability::Vintf }
{%- endif %}
}
{%- if nested|length>0 %}
{{nested}}
Expand Down Expand Up @@ -214,7 +221,11 @@ pub mod {{mod}} {
{%- endfor %}
}
let wrapped = Wrapper { _inner: inner, _rt: rt };
{%- if is_vintf %}
let binder = {{crate}}::native::Binder::new_with_stability({{bn_name}}(Box::new(wrapped)), {{crate}}::Stability::Vintf);
{%- else %}
let binder = {{crate}}::native::Binder::new_with_stability({{bn_name}}(Box::new(wrapped)), {{crate}}::Stability::default());
{%- endif %}
{{crate}}::Strong::new(Box::new(binder))
}
}
Expand Down Expand Up @@ -506,13 +517,19 @@ impl Generator {
Self { enabled_async, is_crate }
}

fn new_context(&self) -> tera::Context {
let mut context = tera::Context::new();
fn get_crate_name(&self) -> &str {
if self.is_crate {
context.insert("crate", "crate");
"crate"
} else {
context.insert("crate", "rsbinder");
"rsbinder"
}
}

fn new_context(&self) -> tera::Context {
let mut context = tera::Context::new();

context.insert("crate", self.get_crate_name());

context
}

Expand Down Expand Up @@ -561,13 +578,10 @@ impl Generator {
}

fn decl_interface(&self, arg_decl: &parser::InterfaceDecl, indent: usize) -> Result<String, Box<dyn Error>> {
let mut is_empty = false;
let mut decl = arg_decl.clone();

if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0 {
is_empty = true;
// return Ok(String::new())
}
let is_empty = parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0;
let is_vintf = parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::VintfStability).0;

decl.pre_process();

Expand All @@ -578,7 +592,10 @@ impl Generator {
for constant in decl.constant_list.iter() {
let generator = constant.r#type.to_generator();
const_members.push((constant.const_identifier(),
generator.const_type_decl(), generator.init_value(constant.const_expr.as_ref(), true)));
generator.const_type_decl(),
generator.init_value(constant.const_expr.as_ref(),
InitParam::builder().with_const(true))
));
}

for method in decl.method_list.iter() {
Expand All @@ -605,6 +622,7 @@ impl Generator {
context.insert("oneway", &decl.oneway);
context.insert("nested", &nested.trim());
context.insert("enabled_async", &enabled_async);
context.insert("is_vintf", &is_vintf);

let rendered = TEMPLATES.render("interface", &context).expect("Failed to render interface template");

Expand All @@ -615,6 +633,8 @@ impl Generator {
let mut is_empty = false;
let mut decl = arg_decl.clone();

let is_vintf = parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::VintfStability).0;

if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0 {
println!("Parcelable {} is only used for Java.", decl.name);
is_empty = true;
Expand All @@ -636,17 +656,30 @@ impl Generator {
// Parse struct variables only.
for decl in &decl.members {
if let Some(var) = decl.is_variable() {
println!("Parcelable variable: {:?}", var);
let generator = var.r#type.to_generator();

if var.constant {
constant_members.push((var.const_identifier(),
generator.const_type_decl(), generator.init_value(var.const_expr.as_ref(), true)));
generator.const_type_decl(),
generator.init_value(var.const_expr.as_ref(),
InitParam::builder().with_const(true))
));
} else {
let init_value = match generator.value_type {
ValueType::Holder => Some(ConstExpr::new(ValueType::Holder)),
_ => var.const_expr.clone()
};

members.push(
(
var.identifier(),
generator.type_declaration(true),
generator.init_value(var.const_expr.as_ref(), false)
generator.init_value(init_value.as_ref(),
InitParam::builder().with_const(false)
.with_vintf(is_vintf)
.with_crate_name(self.get_crate_name())
)
)
)
}
Expand All @@ -669,6 +702,7 @@ impl Generator {
context.insert("members", &members);
context.insert("const_members", &constant_members);
context.insert("nested", &nested.trim());
context.insert("is_vintf", &is_vintf);

let rendered = TEMPLATES.render("parcelable", &context).expect("Failed to render parcelable template");

Expand Down Expand Up @@ -710,6 +744,8 @@ impl Generator {
return Ok(String::new())
}

let is_vintf = parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::VintfStability).0;

let mut constant_members = Vec::new();
let mut members = Vec::new();

Expand All @@ -718,7 +754,9 @@ impl Generator {
let generator = var.r#type.to_generator();
if var.constant {
constant_members.push((var.const_identifier(),
generator.const_type_decl(), generator.init_value(var.const_expr.as_ref(), true)));
generator.const_type_decl(),
generator.init_value(var.const_expr.as_ref(),
InitParam::builder().with_const(true))));
} else {
members.push((var.union_identifier(), generator.type_declaration(true), var.identifier(), generator.default_value()));
}
Expand All @@ -738,6 +776,7 @@ impl Generator {
context.insert("namespace", &namespace);
context.insert("members", &members);
context.insert("const_members", &constant_members);
context.insert("is_vintf", &is_vintf);

let rendered = TEMPLATES.render("union", &context).expect("Failed to render union template");

Expand Down
2 changes: 2 additions & 0 deletions rsbinder-aidl/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,13 @@ pub enum AnnotationType {
IsNullable,
JavaOnly,
RustDerive,
VintfStability,
}

pub fn check_annotation_list(annotation_list: &Vec<Annotation>, query_type: AnnotationType) -> (bool, String) {
for annotation in annotation_list {
match query_type {
AnnotationType::VintfStability if annotation.annotation == "@VintfStability" => return (true, "".to_owned()),
AnnotationType::IsNullable if annotation.annotation == "@nullable" => return (true, "".to_owned()),
AnnotationType::JavaOnly if annotation.annotation.starts_with("@JavaOnly") => return (true, "".to_owned()),
AnnotationType::RustDerive if annotation.annotation == "@RustDerive" => {
Expand Down
17 changes: 12 additions & 5 deletions rsbinder-aidl/src/type_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::sync::OnceLock;

use crate::parser::{*, self};
use crate::const_expr::{ValueType, ConstExpr};
use crate::const_expr::{ValueType, ConstExpr, InitParam};

static CRATE_NAME: OnceLock<String> = OnceLock::new();

Expand Down Expand Up @@ -591,23 +591,30 @@ impl TypeGenerator {
}
}

pub fn init_value(&self, const_expr: Option<&ConstExpr>, is_const: bool) -> String {
pub(crate) fn init_value(&self, const_expr: Option<&ConstExpr>, param: InitParam) -> String {
match const_expr {
Some(expr) => {
let init_str = if let ValueType::Array(_) = self.value_type {
let array_info = self.array_types.first().unwrap();
let is_nullable = self.is_nullable && Self::is_aidl_nullable(&array_info.value_type);
expr.calculate().convert_to(&array_info.value_type).value.to_init(is_const, array_info.is_fixed(), is_nullable)
expr.calculate().convert_to(&array_info.value_type).value.to_init(
param.with_fixed_array(array_info.is_fixed())
.with_nullable(is_nullable))
} else {
expr.calculate().convert_to(&self.value_type).value.to_init(is_const, false, false)
expr.calculate().convert_to(&self.value_type).value.to_init(
param.with_fixed_array(false)
.with_nullable(false)
)
};
if self.is_nullable {
format!("Some({})", init_str)
} else {
init_str
}
}
None => ValueType::Void.to_init(is_const, false, false),
None => ValueType::Void.to_init(param.with_fixed_array(false)
.with_nullable(false)
),
}
}
}
Expand Down
Loading

0 comments on commit 4c1de1d

Please sign in to comment.