Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VintfStability annotation support and passed the related test cases. #22

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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