[banjo] Add support for parsing fidl IR JSON into structs.
This lands initial support for parsing fidl IR JSON. The next step will
be to take the deserialized structs and merge it into our AST
representation so that the types can be used as easily as banjo types.
The JSON schema doesn't match up entirely with the output from fidlc, so
the representations doesn't line up with the schema perfectly.
The test is not comprehensive as it is missing many variations of
structs.
Tested: fx run-host-tests banjo_host_tests
Change-Id: Id8603e829a876ddfdfa09c755fd085403b897854
diff --git a/tools/banjo/banjo/BUILD.gn b/tools/banjo/banjo/BUILD.gn
index 3dee0f5..df08b3d 100644
--- a/tools/banjo/banjo/BUILD.gn
+++ b/tools/banjo/banjo/BUILD.gn
@@ -12,8 +12,10 @@
deps = [
"//third_party/rust_crates:failure",
"//third_party/rust_crates:heck",
+ "//third_party/rust_crates:lazy_static",
"//third_party/rust_crates:pest",
"//third_party/rust_crates:pest_derive",
+ "//third_party/rust_crates:regex",
"//third_party/rust_crates:serde",
"//third_party/rust_crates:serde_derive",
"//third_party/rust_crates:serde_json",
@@ -27,8 +29,10 @@
deps = [
"//third_party/rust_crates:failure",
"//third_party/rust_crates:heck",
+ "//third_party/rust_crates:lazy_static",
"//third_party/rust_crates:pest",
"//third_party/rust_crates:pest_derive",
+ "//third_party/rust_crates:regex",
"//third_party/rust_crates:serde",
"//third_party/rust_crates:serde_derive",
"//third_party/rust_crates:serde_json",
@@ -48,6 +52,8 @@
":banjo_lib($host_toolchain)",
"//third_party/rust_crates:pest",
"//third_party/rust_crates:pretty_assertions",
+ "//third_party/rust_crates:serde",
+ "//third_party/rust_crates:serde_json",
]
source_root = "test/tests.rs"
}
diff --git a/tools/banjo/banjo/src/ast.rs b/tools/banjo/banjo/src/ast.rs
index e171459..ab4a69b 100644
--- a/tools/banjo/banjo/src/ast.rs
+++ b/tools/banjo/banjo/src/ast.rs
@@ -3,6 +3,7 @@
// found in the LICENSE file.
use {
+ crate::fidl,
crate::Rule,
failure::Fail,
pest::iterators::{Pair, Pairs},
@@ -1035,7 +1036,10 @@
Ok(())
}
- pub fn parse(pair_vec: Vec<Pairs<'_, Rule>>) -> Result<Self, ParseError> {
+ pub fn parse(
+ pair_vec: Vec<Pairs<'_, Rule>>,
+ _fidl_vec: Vec<fidl::Ir>,
+ ) -> Result<Self, ParseError> {
let mut primary_namespace = None;
let mut namespaces = BTreeMap::default();
diff --git a/tools/banjo/banjo/src/fidl.rs b/tools/banjo/banjo/src/fidl.rs
new file mode 100644
index 0000000..383a36b
--- /dev/null
+++ b/tools/banjo/banjo/src/fidl.rs
@@ -0,0 +1,435 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Based on https://fuchsia.googlesource.com/fuchsia/+/HEAD/zircon/system/host/fidl/schema.json
+
+use {
+ lazy_static::lazy_static,
+ regex::Regex,
+ serde::{Deserialize, Deserializer},
+ serde_derive::{Deserialize, Serialize},
+ std::collections::BTreeMap,
+};
+
+lazy_static! {
+ pub static ref IDENTIFIER_RE: Regex =
+ Regex::new(r#"^[A-Za-z]([_A-Za-z0-9]*[A-Za-z0-9])?$"#).unwrap();
+ pub static ref COMPOUND_IDENTIFIER_RE: Regex =
+ Regex::new(r#"([_A-Za-z][_A-Za-z0-9]*-)*[_A-Za-z][_A-Za-z0-9]*/[_A-Za-z][_A-Za-z0-9]*"#)
+ .unwrap();
+ pub static ref LIBRARY_IDENTIFIER_RE: Regex =
+ Regex::new(r#"^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)*$"#).unwrap();
+ pub static ref VERSION_RE: Regex = Regex::new(r#"^[0-9]+\.[0-9]+\.[0-9]+$"#).unwrap();
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct Ordinal(#[serde(deserialize_with = "validate_ordinal")] pub u32);
+
+/// Validates that ordinal is non-zero.
+fn validate_ordinal<'de, D>(deserializer: D) -> Result<u32, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let ordinal = u32::deserialize(deserializer)?;
+ if ordinal == 0 {
+ return Err(serde::de::Error::custom("Ordinal must not be equal to 0"));
+ }
+ Ok(ordinal)
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[repr(transparent)]
+pub struct Count(pub u32);
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct Identifier(#[serde(deserialize_with = "validate_identifier")] pub String);
+
+fn validate_identifier<'de, D>(deserializer: D) -> Result<String, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let id = String::deserialize(deserializer)?;
+ if !IDENTIFIER_RE.is_match(&id) {
+ return Err(serde::de::Error::custom(format!("Invalid identifier: {}", id)));
+ }
+ Ok(id)
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct CompoundIdentifier(
+ #[serde(deserialize_with = "validate_compound_identifier")] pub String,
+);
+
+fn validate_compound_identifier<'de, D>(deserializer: D) -> Result<String, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let id = String::deserialize(deserializer)?;
+ if !COMPOUND_IDENTIFIER_RE.is_match(&id) {
+ return Err(serde::de::Error::custom(format!("Invalid compound identifier: {}", id)));
+ }
+ Ok(id)
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct LibraryIdentifier(#[serde(deserialize_with = "validate_library_identifier")] pub String);
+
+fn validate_library_identifier<'de, D>(deserializer: D) -> Result<String, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let id = String::deserialize(deserializer)?;
+ if !LIBRARY_IDENTIFIER_RE.is_match(&id) {
+ return Err(serde::de::Error::custom(format!("Invalid library identifier: {}", id)));
+ }
+ Ok(id)
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct Version(#[serde(deserialize_with = "validate_version")] pub String);
+
+fn validate_version<'de, D>(deserializer: D) -> Result<String, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let version = String::deserialize(deserializer)?;
+ if !VERSION_RE.is_match(&version) {
+ return Err(serde::de::Error::custom(format!("Invalid version: {}", version)));
+ }
+ Ok(version)
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum Declaration {
+ Const,
+ Enum,
+ Interface,
+ Struct,
+ Table,
+ Union,
+ XUnion,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct DeclarationsMap(pub BTreeMap<CompoundIdentifier, Declaration>);
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Library {
+ pub name: LibraryIdentifier,
+ pub declarations: DeclarationsMap,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Location {
+ pub filename: String,
+ pub line: u32,
+ pub column: u32,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum HandleSubtype {
+ Handle,
+ Process,
+ Thread,
+ Vmo,
+ Channel,
+ Event,
+ Port,
+ Interrupt,
+ Debuglog,
+ Socket,
+ Resource,
+ Eventpair,
+ Job,
+ Vmar,
+ Fifo,
+ Guest,
+ Timer,
+ Bti,
+ Profile,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum IntegerType {
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Uint8,
+ Uint16,
+ Uint32,
+ Uint64,
+}
+
+// TODO(surajmalhotra): Implement conversion begtween IntegerType and PrimitiveSubtype.
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum PrimitiveSubtype {
+ Bool,
+ Float32,
+ Float64,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Uint8,
+ Uint16,
+ Uint32,
+ Uint64,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum Type {
+ Array {
+ element_type: Box<Type>,
+ element_count: Count,
+ },
+ Vector {
+ element_type: Box<Type>,
+ maybe_element_count: Option<Count>,
+ nullable: bool,
+ },
+ #[serde(rename = "string")]
+ Str {
+ maybe_element_count: Option<Count>,
+ nullable: bool,
+ },
+ Handle {
+ subtype: HandleSubtype,
+ nullable: bool,
+ },
+ Request {
+ subtype: CompoundIdentifier,
+ nullable: bool,
+ },
+ Primitive {
+ subtype: PrimitiveSubtype,
+ },
+ Identifier {
+ identifier: CompoundIdentifier,
+ nullable: bool,
+ },
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum Literal {
+ #[serde(rename = "string")]
+ Str {
+ value: String,
+ },
+ Numeric {
+ value: String,
+ },
+ True,
+ False,
+ #[serde(rename = "default")]
+ _Default,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum Constant {
+ Identifier { identifier: CompoundIdentifier },
+ Literal { literal: Literal },
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Const {
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ #[serde(rename = "type")]
+ pub _type: Type,
+ pub value: Constant,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct EnumMember {
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub value: Constant,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Enum {
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ #[serde(rename = "type")]
+ pub _type: IntegerType,
+ pub members: Vec<EnumMember>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Attribute {
+ pub name: String,
+ pub value: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct MethodParameter {
+ #[serde(rename = "type")]
+ pub _type: Type,
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+ pub offset: Count,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Method {
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub ordinal: Ordinal,
+ pub generated_ordinal: Ordinal,
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub has_request: bool,
+ pub maybe_request: Option<Vec<MethodParameter>>,
+ pub maybe_request_size: Option<Count>,
+ pub maybe_request_alignment: Option<Count>,
+ pub has_response: bool,
+ pub maybe_response: Option<Vec<MethodParameter>>,
+ pub maybe_response_size: Option<Count>,
+ pub maybe_response_alignment: Option<Count>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Interface {
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ pub methods: Vec<Method>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct StructMember {
+ #[serde(rename = "type")]
+ pub _type: Type,
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+ pub offset: Count,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub maybe_default_value: Option<Constant>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Struct {
+ pub max_handles: Option<Count>,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ pub anonymous: Option<bool>,
+ pub members: Vec<StructMember>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
+pub struct TableMember {
+ pub ordinal: Ordinal,
+ pub reserved: bool,
+ #[serde(rename = "type")]
+ pub _type: Option<Type>,
+ pub name: Option<Identifier>,
+ pub location: Option<Location>,
+ pub size: Option<Count>,
+ pub max_out_of_line: Option<Count>,
+ pub alignment: Option<Count>,
+ pub offset: Option<Count>,
+ pub maybe_default_value: Option<Constant>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Table {
+ pub max_handles: Option<Count>,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ pub members: Vec<TableMember>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct UnionMember {
+ #[serde(rename = "type")]
+ pub _type: Type,
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+ pub offset: Count,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Union {
+ pub max_handles: Option<Count>,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ pub members: Vec<UnionMember>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct XUnionMember {
+ pub ordinal: Ordinal,
+ #[serde(rename = "type")]
+ pub _type: Type,
+ pub name: Identifier,
+ pub location: Option<Location>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+ pub offset: Count,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct XUnion {
+ pub max_handles: Option<Count>,
+ pub maybe_attributes: Option<Vec<Attribute>>,
+ pub name: CompoundIdentifier,
+ pub location: Option<Location>,
+ pub members: Vec<XUnionMember>,
+ pub size: Count,
+ pub max_out_of_line: Count,
+ pub alignment: Count,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Ir {
+ pub version: Version,
+ pub name: LibraryIdentifier,
+ pub library_dependencies: Vec<Library>,
+ pub const_declarations: Vec<Const>,
+ pub enum_declarations: Vec<Enum>,
+ pub interface_declarations: Vec<Interface>,
+ pub struct_declarations: Vec<Struct>,
+ pub table_declarations: Vec<Table>,
+ pub union_declarations: Vec<Union>,
+ pub xunion_declarations: Vec<XUnion>,
+ pub declaration_order: Vec<CompoundIdentifier>,
+ pub declarations: DeclarationsMap,
+}
diff --git a/tools/banjo/banjo/src/lib.rs b/tools/banjo/banjo/src/lib.rs
index 9c663b8..a9ebf1b 100644
--- a/tools/banjo/banjo/src/lib.rs
+++ b/tools/banjo/banjo/src/lib.rs
@@ -8,4 +8,5 @@
pub mod ast;
pub mod backends;
+pub mod fidl;
pub mod parser;
diff --git a/tools/banjo/banjo/src/main.rs b/tools/banjo/banjo/src/main.rs
index 76b0867..ed95d6a 100644
--- a/tools/banjo/banjo/src/main.rs
+++ b/tools/banjo/banjo/src/main.rs
@@ -18,6 +18,7 @@
mod ast;
mod backends;
+mod fidl;
mod parser;
#[derive(Debug)]
@@ -72,10 +73,16 @@
#[structopt(short = "b", long = "backend")]
backend: BackendName,
- /// Files to process
+ /// Banjo IDL files to process. These are expected to be in the format described by
+ /// https://fuchsia.googlesource.com/fuchsia/+/HEAD/zircon/docs/ddk/banjo-tutorial.md#reference
#[structopt(short = "f", long = "files", parse(from_os_str))]
input: Vec<PathBuf>,
+ /// FIDL IR JSON files to process. These files are expected to be in the format described by
+ /// https://fuchsia.googlesource.com/fuchsia/+/HEAD/zircon/system/host/fidl/schema.json
+ #[structopt(short = "i", long = "fidl-ir", parse(from_os_str))]
+ fidl_ir: Vec<PathBuf>,
+
/// Don't include default zx types
#[structopt(long = "omit-zx")]
no_zx: bool,
@@ -109,6 +116,7 @@
let opt = Opt::from_iter(args);
let mut pair_vec = Vec::new();
+ let mut fidl_vec = Vec::new();
let files: Vec<String> = opt
.input
.iter()
@@ -120,6 +128,17 @@
})
.collect();
+ let fidl_files: Vec<String> = opt
+ .fidl_ir
+ .iter()
+ .map(|filename| {
+ let mut f = File::open(filename).expect(&format!("{} not found", filename.display()));
+ let mut contents = String::new();
+ f.read_to_string(&mut contents).expect("something went wrong reading the file");
+ contents
+ })
+ .collect();
+
if !opt.no_zx {
let zx_file = include_str!("../zx.banjo");
pair_vec.push(BanjoParser::parse(Rule::file, zx_file)?);
@@ -127,8 +146,11 @@
for file in files.iter() {
pair_vec.push(BanjoParser::parse(Rule::file, file.as_str())?);
}
+ for file in fidl_files.iter() {
+ fidl_vec.push(serde_json::from_str(file.as_str())?);
+ }
- let ast = BanjoAst::parse(pair_vec)?;
+ let ast = BanjoAst::parse(pair_vec, fidl_vec)?;
let mut output: Box<dyn io::Write> = if let Some(output) = opt.output {
Box::new(File::create(output)?)
} else {
diff --git a/tools/banjo/banjo/test/fidl/test.fidl.json b/tools/banjo/banjo/test/fidl/test.fidl.json
new file mode 100644
index 0000000..898c3a7
--- /dev/null
+++ b/tools/banjo/banjo/test/fidl/test.fidl.json
@@ -0,0 +1,535 @@
+{
+ "version": "0.0.1",
+ "name": "fidl.test.misc",
+ "library_dependencies": [],
+ "const_declarations": [],
+ "enum_declarations": [],
+ "interface_declarations": [],
+ "struct_declarations": [
+ {
+ "name": "fidl.test.misc/Int64Struct",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 7,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [
+ {
+ "type": {
+ "kind": "primitive",
+ "subtype": "int64"
+ },
+ "name": "x",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 8,
+ "column": 10
+ },
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ }
+ ],
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.misc/HasOptionalFieldStruct",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 11,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Int64Struct",
+ "nullable": true
+ },
+ "name": "x",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 12,
+ "column": 17
+ },
+ "size": 8,
+ "max_out_of_line": 8,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ }
+ ],
+ "size": 8,
+ "max_out_of_line": 8,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.misc/Has2OptionalFieldStruct",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 15,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Int64Struct",
+ "nullable": true
+ },
+ "name": "x",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 16,
+ "column": 17
+ },
+ "size": 8,
+ "max_out_of_line": 8,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Int64Struct",
+ "nullable": true
+ },
+ "name": "y",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 17,
+ "column": 17
+ },
+ "size": 8,
+ "max_out_of_line": 8,
+ "alignment": 8,
+ "offset": 8,
+ "max_handles": 0
+ }
+ ],
+ "size": 16,
+ "max_out_of_line": 16,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.misc/Empty",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 20,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [],
+ "size": 1,
+ "max_out_of_line": 0,
+ "alignment": 1,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.misc/EmptyStructSandwich",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 23,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [
+ {
+ "type": {
+ "kind": "string",
+ "nullable": false
+ },
+ "name": "before",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 24,
+ "column": 11
+ },
+ "size": 16,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Empty",
+ "nullable": false
+ },
+ "name": "e",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 25,
+ "column": 10
+ },
+ "size": 1,
+ "max_out_of_line": 0,
+ "alignment": 1,
+ "offset": 16,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "string",
+ "nullable": false
+ },
+ "name": "after",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 26,
+ "column": 11
+ },
+ "size": 16,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 24,
+ "max_handles": 0
+ }
+ ],
+ "size": 40,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.misc/InlineXUnionInStruct",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 70,
+ "column": 7
+ },
+ "anonymous": false,
+ "members": [
+ {
+ "type": {
+ "kind": "string",
+ "nullable": false
+ },
+ "name": "before",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 71,
+ "column": 11
+ },
+ "size": 16,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/SampleXUnion",
+ "nullable": false
+ },
+ "name": "xu",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 72,
+ "column": 17
+ },
+ "size": 24,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 16,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "string",
+ "nullable": false
+ },
+ "name": "after",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 73,
+ "column": 11
+ },
+ "size": 16,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 40,
+ "max_handles": 0
+ }
+ ],
+ "size": 56,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "table_declarations": [
+ {
+ "name": "fidl.test.misc/SimpleTable",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 37,
+ "column": 6
+ },
+ "members": [
+ {
+ "ordinal": 1,
+ "reserved": false,
+ "type": {
+ "kind": "primitive",
+ "subtype": "int64"
+ },
+ "name": "x",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 38,
+ "column": 13
+ },
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "ordinal": 2,
+ "reserved": true
+ },
+ {
+ "ordinal": 3,
+ "reserved": true
+ },
+ {
+ "ordinal": 4,
+ "reserved": true
+ },
+ {
+ "ordinal": 5,
+ "reserved": false,
+ "type": {
+ "kind": "primitive",
+ "subtype": "int64"
+ },
+ "name": "y",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 42,
+ "column": 13
+ },
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "size": 16,
+ "max_out_of_line": 48,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "union_declarations": [
+ {
+ "name": "fidl.test.misc/SimpleUnion",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 29,
+ "column": 6
+ },
+ "members": [
+ {
+ "type": {
+ "kind": "primitive",
+ "subtype": "int32"
+ },
+ "name": "i32",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 30,
+ "column": 10
+ },
+ "size": 4,
+ "max_out_of_line": 0,
+ "alignment": 4,
+ "offset": 8
+ },
+ {
+ "type": {
+ "kind": "primitive",
+ "subtype": "int64"
+ },
+ "name": "i64",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 31,
+ "column": 10
+ },
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "offset": 8
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Int64Struct",
+ "nullable": false
+ },
+ "name": "s",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 32,
+ "column": 16
+ },
+ "size": 8,
+ "max_out_of_line": 0,
+ "alignment": 8,
+ "offset": 8
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/Int64Struct",
+ "nullable": true
+ },
+ "name": "os",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 33,
+ "column": 17
+ },
+ "size": 8,
+ "max_out_of_line": 8,
+ "alignment": 8,
+ "offset": 8
+ },
+ {
+ "type": {
+ "kind": "string",
+ "nullable": false
+ },
+ "name": "str",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 34,
+ "column": 11
+ },
+ "size": 16,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 8
+ }
+ ],
+ "size": 24,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "xunion_declarations": [
+ {
+ "name": "fidl.test.misc/SampleXUnion",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 64,
+ "column": 7
+ },
+ "members": [
+ {
+ "ordinal": 702498725,
+ "type": {
+ "kind": "primitive",
+ "subtype": "int32"
+ },
+ "name": "i",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 65,
+ "column": 10
+ },
+ "size": 4,
+ "max_out_of_line": 0,
+ "alignment": 4,
+ "offset": 0
+ },
+ {
+ "ordinal": 1865512531,
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/SimpleUnion",
+ "nullable": false
+ },
+ "name": "su",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 66,
+ "column": 16
+ },
+ "size": 24,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "offset": 0
+ },
+ {
+ "ordinal": 811936989,
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.misc/SimpleTable",
+ "nullable": false
+ },
+ "name": "st",
+ "location": {
+ "filename": "../../sdk/lib/fidl/cpp/fidl_test.fidl",
+ "line": 67,
+ "column": 16
+ },
+ "size": 16,
+ "max_out_of_line": 48,
+ "alignment": 8,
+ "offset": 0
+ }
+ ],
+ "size": 24,
+ "max_out_of_line": 4294967295,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "declaration_order": [
+ "fidl.test.misc/Has2OptionalFieldStruct",
+ "fidl.test.misc/OptionalXUnionInStruct",
+ "fidl.test.misc/HasOptionalFieldStruct",
+ "fidl.test.misc/OlderSimpleTable",
+ "fidl.test.misc/NewerSimpleTable",
+ "fidl.test.misc/SimpleTable",
+ "fidl.test.misc/Int64Struct",
+ "fidl.test.misc/SimpleUnion",
+ "fidl.test.misc/SampleXUnion",
+ "fidl.test.misc/InlineXUnionInStruct",
+ "fidl.test.misc/XUnionInTable",
+ "fidl.test.misc/Empty",
+ "fidl.test.misc/EmptyStructSandwich"
+ ],
+ "declarations": {
+ "fidl.test.misc/Int64Struct": "struct",
+ "fidl.test.misc/HasOptionalFieldStruct": "struct",
+ "fidl.test.misc/Has2OptionalFieldStruct": "struct",
+ "fidl.test.misc/Empty": "struct",
+ "fidl.test.misc/EmptyStructSandwich": "struct",
+ "fidl.test.misc/InlineXUnionInStruct": "struct",
+ "fidl.test.misc/OptionalXUnionInStruct": "struct",
+ "fidl.test.misc/SimpleTable": "table",
+ "fidl.test.misc/OlderSimpleTable": "table",
+ "fidl.test.misc/NewerSimpleTable": "table",
+ "fidl.test.misc/XUnionInTable": "table",
+ "fidl.test.misc/SimpleUnion": "union",
+ "fidl.test.misc/SampleXUnion": "xunion"
+ }
+}
diff --git a/tools/banjo/banjo/test/fidl_tests.rs b/tools/banjo/banjo/test/fidl_tests.rs
new file mode 100644
index 0000000..1526de8
--- /dev/null
+++ b/tools/banjo/banjo/test/fidl_tests.rs
@@ -0,0 +1,587 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#![cfg(test)]
+
+use pretty_assertions::assert_eq;
+use serde_json;
+use std::collections::BTreeMap;
+
+#[test]
+fn fidl_ir() {
+ use banjo_lib::fidl;
+ let input = include_str!("fidl/test.fidl.json");
+ let mut decls = BTreeMap::new();
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/Int64Struct".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/HasOptionalFieldStruct".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/Has2OptionalFieldStruct".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/Empty".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/EmptyStructSandwich".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/InlineXUnionInStruct".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/OptionalXUnionInStruct".to_string()),
+ fidl::Declaration::Struct,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/SimpleTable".to_string()),
+ fidl::Declaration::Table,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/OlderSimpleTable".to_string()),
+ fidl::Declaration::Table,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/NewerSimpleTable".to_string()),
+ fidl::Declaration::Table,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/XUnionInTable".to_string()),
+ fidl::Declaration::Table,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/SimpleUnion".to_string()),
+ fidl::Declaration::Union,
+ );
+ decls.insert(
+ fidl::CompoundIdentifier("fidl.test.misc/SampleXUnion".to_string()),
+ fidl::Declaration::XUnion,
+ );
+ let decls = decls;
+
+ let expected = fidl::Ir {
+ version: fidl::Version("0.0.1".to_string()),
+ name: fidl::LibraryIdentifier("fidl.test.misc".to_string()),
+ const_declarations: vec![],
+ enum_declarations: vec![],
+ interface_declarations: vec![],
+ struct_declarations: vec![
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/Int64Struct".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 7,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![fidl::StructMember {
+ _type: fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int64 },
+ name: fidl::Identifier("x".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 8,
+ column: 10,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ }],
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(0),
+ },
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/HasOptionalFieldStruct".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 11,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![fidl::StructMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Int64Struct".to_string(),
+ ),
+ nullable: true,
+ },
+ name: fidl::Identifier("x".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 12,
+ column: 17,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(8),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ }],
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(8),
+ },
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier(
+ "fidl.test.misc/Has2OptionalFieldStruct".to_string(),
+ ),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 15,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![
+ fidl::StructMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Int64Struct".to_string(),
+ ),
+ nullable: true,
+ },
+ name: fidl::Identifier("x".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 16,
+ column: 17,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(8),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ fidl::StructMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Int64Struct".to_string(),
+ ),
+ nullable: true,
+ },
+ name: fidl::Identifier("y".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 17,
+ column: 17,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(8),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ ],
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(16),
+ },
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/Empty".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 20,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![],
+ size: fidl::Count(1),
+ max_out_of_line: fidl::Count(0),
+ },
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/EmptyStructSandwich".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 23,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![
+ fidl::StructMember {
+ _type: fidl::Type::Str { maybe_element_count: None, nullable: false },
+ name: fidl::Identifier("before".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 24,
+ column: 11,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ fidl::StructMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Empty".to_string(),
+ ),
+ nullable: false,
+ },
+ name: fidl::Identifier("e".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 25,
+ column: 10,
+ }),
+ size: fidl::Count(1),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(1),
+ offset: fidl::Count(16),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ fidl::StructMember {
+ _type: fidl::Type::Str { maybe_element_count: None, nullable: false },
+ name: fidl::Identifier("after".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 26,
+ column: 11,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(24),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ ],
+ size: fidl::Count(40),
+ max_out_of_line: fidl::Count(4294967295),
+ },
+ fidl::Struct {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/InlineXUnionInStruct".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 70,
+ column: 7,
+ }),
+ anonymous: Some(false),
+ members: vec![
+ fidl::StructMember {
+ _type: fidl::Type::Str { maybe_element_count: None, nullable: false },
+ name: fidl::Identifier("before".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 71,
+ column: 11,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ fidl::StructMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/SampleXUnion".to_string(),
+ ),
+ nullable: false,
+ },
+ name: fidl::Identifier("xu".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 72,
+ column: 17,
+ }),
+ size: fidl::Count(24),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(16),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ fidl::StructMember {
+ _type: fidl::Type::Str { maybe_element_count: None, nullable: false },
+ name: fidl::Identifier("after".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 73,
+ column: 11,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(40),
+ maybe_attributes: None,
+ maybe_default_value: None,
+ },
+ ],
+ size: fidl::Count(56),
+ max_out_of_line: fidl::Count(4294967295),
+ },
+ ],
+ table_declarations: vec![fidl::Table {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/SimpleTable".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 37,
+ column: 6,
+ }),
+ members: vec![
+ fidl::TableMember {
+ ordinal: fidl::Ordinal(1),
+ reserved: false,
+ _type: Some(fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int64 }),
+ name: Some(fidl::Identifier("x".to_string())),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 38,
+ column: 13,
+ }),
+ size: Some(fidl::Count(8)),
+ max_out_of_line: Some(fidl::Count(0)),
+ alignment: Some(fidl::Count(8)),
+ offset: None,
+ maybe_default_value: None,
+ },
+ fidl::TableMember {
+ ordinal: fidl::Ordinal(2),
+ reserved: true,
+ ..Default::default()
+ },
+ fidl::TableMember {
+ ordinal: fidl::Ordinal(3),
+ reserved: true,
+ ..Default::default()
+ },
+ fidl::TableMember {
+ ordinal: fidl::Ordinal(4),
+ reserved: true,
+ ..Default::default()
+ },
+ fidl::TableMember {
+ ordinal: fidl::Ordinal(5),
+ reserved: false,
+ _type: Some(fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int64 }),
+ name: Some(fidl::Identifier("y".to_string())),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 42,
+ column: 13,
+ }),
+ size: Some(fidl::Count(8)),
+ max_out_of_line: Some(fidl::Count(0)),
+ alignment: Some(fidl::Count(8)),
+ offset: None,
+ maybe_default_value: None,
+ },
+ ],
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(48),
+ }],
+ union_declarations: vec![fidl::Union {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/SimpleUnion".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 29,
+ column: 6,
+ }),
+ members: vec![
+ fidl::UnionMember {
+ _type: fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int32 },
+ name: fidl::Identifier("i32".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 30,
+ column: 10,
+ }),
+ size: fidl::Count(4),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(4),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ },
+ fidl::UnionMember {
+ _type: fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int64 },
+ name: fidl::Identifier("i64".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 31,
+ column: 10,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ },
+ fidl::UnionMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Int64Struct".to_string(),
+ ),
+ nullable: false,
+ },
+ name: fidl::Identifier("s".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 32,
+ column: 16,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ },
+ fidl::UnionMember {
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/Int64Struct".to_string(),
+ ),
+ nullable: true,
+ },
+ name: fidl::Identifier("os".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 33,
+ column: 17,
+ }),
+ size: fidl::Count(8),
+ max_out_of_line: fidl::Count(8),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ },
+ fidl::UnionMember {
+ _type: fidl::Type::Str { maybe_element_count: None, nullable: false },
+ name: fidl::Identifier("str".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 34,
+ column: 11,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(8),
+ maybe_attributes: None,
+ },
+ ],
+ size: fidl::Count(24),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ }],
+ xunion_declarations: vec![fidl::XUnion {
+ max_handles: Some(fidl::Count(0)),
+ maybe_attributes: None,
+ name: fidl::CompoundIdentifier("fidl.test.misc/SampleXUnion".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 64,
+ column: 7,
+ }),
+ members: vec![
+ fidl::XUnionMember {
+ ordinal: fidl::Ordinal(702498725),
+ _type: fidl::Type::Primitive { subtype: fidl::PrimitiveSubtype::Int32 },
+ name: fidl::Identifier("i".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 65,
+ column: 10,
+ }),
+ size: fidl::Count(4),
+ max_out_of_line: fidl::Count(0),
+ alignment: fidl::Count(4),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ },
+ fidl::XUnionMember {
+ ordinal: fidl::Ordinal(1865512531),
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/SimpleUnion".to_string(),
+ ),
+ nullable: false,
+ },
+ name: fidl::Identifier("su".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 66,
+ column: 16,
+ }),
+ size: fidl::Count(24),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ },
+ fidl::XUnionMember {
+ ordinal: fidl::Ordinal(811936989),
+ _type: fidl::Type::Identifier {
+ identifier: fidl::CompoundIdentifier(
+ "fidl.test.misc/SimpleTable".to_string(),
+ ),
+ nullable: false,
+ },
+ name: fidl::Identifier("st".to_string()),
+ location: Some(fidl::Location {
+ filename: "../../sdk/lib/fidl/cpp/fidl_test.fidl".to_string(),
+ line: 67,
+ column: 16,
+ }),
+ size: fidl::Count(16),
+ max_out_of_line: fidl::Count(48),
+ alignment: fidl::Count(8),
+ offset: fidl::Count(0),
+ maybe_attributes: None,
+ },
+ ],
+ size: fidl::Count(24),
+ max_out_of_line: fidl::Count(4294967295),
+ alignment: fidl::Count(8),
+ }],
+ declaration_order: vec![
+ fidl::CompoundIdentifier("fidl.test.misc/Has2OptionalFieldStruct".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/OptionalXUnionInStruct".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/HasOptionalFieldStruct".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/OlderSimpleTable".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/NewerSimpleTable".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/SimpleTable".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/Int64Struct".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/SimpleUnion".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/SampleXUnion".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/InlineXUnionInStruct".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/XUnionInTable".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/Empty".to_string()),
+ fidl::CompoundIdentifier("fidl.test.misc/EmptyStructSandwich".to_string()),
+ ],
+ declarations: fidl::DeclarationsMap(decls),
+ library_dependencies: vec![],
+ };
+
+ let ir: fidl::Ir = serde_json::from_str(input).unwrap();
+ assert_eq!(ir, expected)
+}
diff --git a/tools/banjo/banjo/test/tests.rs b/tools/banjo/banjo/test/tests.rs
index 19e9846..c7ce109 100644
--- a/tools/banjo/banjo/test/tests.rs
+++ b/tools/banjo/banjo/test/tests.rs
@@ -6,6 +6,7 @@
mod ast_tests;
mod codegen_tests;
+mod fidl_tests;
/// Asserts the left and right hand side are the same ignoring new line characters
#[macro_export]
@@ -61,7 +62,7 @@
)*
};
- let ast = banjo_lib::ast::BanjoAst::parse(pair_vec).unwrap();
+ let ast = banjo_lib::ast::BanjoAst::parse(pair_vec, Vec::new()).unwrap();
{
let mut backend: Box<dyn backends::Backend<_>> =
Box::new(backends::$backend::new(&mut output));