mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2025-02-20 00:21:08 +00:00
Extract variant info from ast dump
This commit is contained in:
parent
cacfa023a4
commit
8a893c79ed
@ -1,5 +1,8 @@
|
||||
use crate::syntax::attrs::OtherAttrs;
|
||||
use crate::syntax::namespace::Namespace;
|
||||
use crate::syntax::report::Errors;
|
||||
use crate::syntax::Api;
|
||||
use crate::syntax::{Api, Doc, Enum, ForeignName, Pair, Variant};
|
||||
use proc_macro2::Ident;
|
||||
use serde::Deserialize;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
@ -11,11 +14,29 @@ type Node = clang_ast::Node<Clang>;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum Clang {
|
||||
NamespaceDecl(NamespaceDecl),
|
||||
EnumDecl(EnumDecl),
|
||||
EnumConstantDecl(EnumConstantDecl),
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct NamespaceDecl {
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct EnumDecl {
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct EnumConstantDecl {
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn load(cx: &mut Errors, apis: &mut [Api]) {
|
||||
let mut variants_from_header = Vec::new();
|
||||
let ref mut variants_from_header = Vec::new();
|
||||
for api in apis {
|
||||
if let Api::Enum(enm) = api {
|
||||
if enm.variants_from_header {
|
||||
@ -48,7 +69,7 @@ pub fn load(cx: &mut Errors, apis: &mut [Api]) {
|
||||
}
|
||||
};
|
||||
|
||||
let root: Node = match serde_json::from_slice(&ast_dump_bytes) {
|
||||
let ref root: Node = match serde_json::from_slice(&ast_dump_bytes) {
|
||||
Ok(root) => root,
|
||||
Err(error) => {
|
||||
let msg = format!("failed to read {}: {}", ast_dump_path.display(), error);
|
||||
@ -56,5 +77,80 @@ pub fn load(cx: &mut Errors, apis: &mut [Api]) {
|
||||
}
|
||||
};
|
||||
|
||||
unimplemented!()
|
||||
let ref mut namespace = Vec::new();
|
||||
traverse(root, namespace, variants_from_header, None);
|
||||
}
|
||||
|
||||
fn traverse<'a>(
|
||||
node: &'a Node,
|
||||
namespace: &mut Vec<&'a str>,
|
||||
variants_from_header: &mut [&mut Enum],
|
||||
mut idx: Option<usize>,
|
||||
) {
|
||||
match &node.kind {
|
||||
Clang::NamespaceDecl(decl) => {
|
||||
let name = match &decl.name {
|
||||
Some(name) => name,
|
||||
// Can ignore enums inside an anonymous namespace.
|
||||
None => return,
|
||||
};
|
||||
namespace.push(name);
|
||||
idx = None;
|
||||
}
|
||||
Clang::EnumDecl(decl) => {
|
||||
let name = match &decl.name {
|
||||
Some(name) => name,
|
||||
None => return,
|
||||
};
|
||||
idx = None;
|
||||
for (i, enm) in variants_from_header.iter().enumerate() {
|
||||
if enm.name.cxx == **name && enm.name.namespace.iter().eq(&*namespace) {
|
||||
idx = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if idx.is_none() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Clang::EnumConstantDecl(decl) => {
|
||||
if let Some(idx) = idx {
|
||||
let enm = &mut *variants_from_header[idx];
|
||||
let span = enm
|
||||
.variants_from_header_attr
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.path
|
||||
.get_ident()
|
||||
.unwrap()
|
||||
.span();
|
||||
let cxx_name = match ForeignName::parse(&decl.name, span) {
|
||||
Ok(foreign_name) => foreign_name,
|
||||
Err(_) => return,
|
||||
};
|
||||
let rust_name: Ident = match syn::parse_str(&decl.name) {
|
||||
Ok(ident) => ident,
|
||||
Err(_) => return,
|
||||
};
|
||||
enm.variants.push(Variant {
|
||||
doc: Doc::new(),
|
||||
attrs: OtherAttrs::none(),
|
||||
name: Pair {
|
||||
namespace: Namespace::ROOT,
|
||||
cxx: cxx_name,
|
||||
rust: rust_name,
|
||||
},
|
||||
discriminant: unimplemented!(),
|
||||
expr: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for inner in &node.inner {
|
||||
traverse(inner, namespace, variants_from_header, idx);
|
||||
}
|
||||
if let Clang::NamespaceDecl(_) = &node.kind {
|
||||
let _ = namespace.pop().unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -68,3 +68,9 @@ impl Display for ForeignName {
|
||||
formatter.write_str(&self.text)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for ForeignName {
|
||||
fn eq(&self, rhs: &str) -> bool {
|
||||
self.text == rhs
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user