mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-23 07:10:29 +00:00
Handle module-level cfg attributes
This commit is contained in:
parent
abc64e24d1
commit
c1f2176154
@ -16,25 +16,29 @@ impl CfgEvaluator for UnsupportedCfgEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn strip(cx: &mut Errors, cfg_evaluator: &dyn CfgEvaluator, apis: &mut Vec<Api>) {
|
||||
let mut already_errors = Set::new();
|
||||
apis.retain(|api| eval(cx, &mut already_errors, cfg_evaluator, api.cfg()));
|
||||
pub(super) fn strip(
|
||||
cx: &mut Errors,
|
||||
cfg_errors: &mut Set<String>,
|
||||
cfg_evaluator: &dyn CfgEvaluator,
|
||||
apis: &mut Vec<Api>,
|
||||
) {
|
||||
apis.retain(|api| eval(cx, cfg_errors, cfg_evaluator, api.cfg()));
|
||||
for api in apis {
|
||||
match api {
|
||||
Api::Struct(strct) => strct
|
||||
.fields
|
||||
.retain(|field| eval(cx, &mut already_errors, cfg_evaluator, &field.cfg)),
|
||||
.retain(|field| eval(cx, cfg_errors, cfg_evaluator, &field.cfg)),
|
||||
Api::Enum(enm) => enm
|
||||
.variants
|
||||
.retain(|variant| eval(cx, &mut already_errors, cfg_evaluator, &variant.cfg)),
|
||||
.retain(|variant| eval(cx, cfg_errors, cfg_evaluator, &variant.cfg)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eval(
|
||||
pub(super) fn eval(
|
||||
cx: &mut Errors,
|
||||
already_errors: &mut Set<String>,
|
||||
cfg_errors: &mut Set<String>,
|
||||
cfg_evaluator: &dyn CfgEvaluator,
|
||||
expr: &CfgExpr,
|
||||
) -> bool {
|
||||
@ -47,7 +51,7 @@ fn eval(
|
||||
CfgResult::True => true,
|
||||
CfgResult::False => false,
|
||||
CfgResult::Undetermined { msg } => {
|
||||
if already_errors.insert(msg.clone()) {
|
||||
if cfg_errors.insert(msg.clone()) {
|
||||
let span = quote!(#ident #string);
|
||||
cx.error(span, msg);
|
||||
}
|
||||
@ -57,11 +61,11 @@ fn eval(
|
||||
}
|
||||
CfgExpr::All(list) => list
|
||||
.iter()
|
||||
.all(|expr| eval(cx, already_errors, cfg_evaluator, expr)),
|
||||
.all(|expr| eval(cx, cfg_errors, cfg_evaluator, expr)),
|
||||
CfgExpr::Any(list) => list
|
||||
.iter()
|
||||
.any(|expr| eval(cx, already_errors, cfg_evaluator, expr)),
|
||||
CfgExpr::Not(expr) => !eval(cx, already_errors, cfg_evaluator, expr),
|
||||
.any(|expr| eval(cx, cfg_errors, cfg_evaluator, expr)),
|
||||
CfgExpr::Not(expr) => !eval(cx, cfg_errors, cfg_evaluator, expr),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,10 @@ use self::cfg::UnsupportedCfgEvaluator;
|
||||
use self::error::{format_err, Result};
|
||||
use self::file::File;
|
||||
use self::include::Include;
|
||||
use crate::syntax::cfg::CfgExpr;
|
||||
use crate::syntax::report::Errors;
|
||||
use crate::syntax::{self, Types};
|
||||
use crate::syntax::{self, attrs, Types};
|
||||
use std::collections::BTreeSet as Set;
|
||||
use std::path::Path;
|
||||
|
||||
pub(super) use self::error::Error;
|
||||
@ -132,18 +134,31 @@ pub(super) fn generate(syntax: File, opt: &Opt) -> Result<GeneratedCode> {
|
||||
|
||||
let ref mut apis = Vec::new();
|
||||
let ref mut errors = Errors::new();
|
||||
let ref mut cfg_errors = Set::new();
|
||||
for bridge in syntax.modules {
|
||||
let ref namespace = bridge.namespace;
|
||||
let trusted = bridge.unsafety.is_some();
|
||||
apis.extend(syntax::parse_items(
|
||||
let mut cfg = CfgExpr::Unconditional;
|
||||
attrs::parse(
|
||||
errors,
|
||||
bridge.content,
|
||||
trusted,
|
||||
namespace,
|
||||
));
|
||||
bridge.attrs,
|
||||
attrs::Parser {
|
||||
cfg: Some(&mut cfg),
|
||||
ignore_unrecognized: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
if cfg::eval(errors, cfg_errors, opt.cfg_evaluator.as_ref(), &cfg) {
|
||||
let ref namespace = bridge.namespace;
|
||||
let trusted = bridge.unsafety.is_some();
|
||||
apis.extend(syntax::parse_items(
|
||||
errors,
|
||||
bridge.content,
|
||||
trusted,
|
||||
namespace,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
cfg::strip(errors, opt.cfg_evaluator.as_ref(), apis);
|
||||
cfg::strip(errors, cfg_errors, opt.cfg_evaluator.as_ref(), apis);
|
||||
errors.propagate()?;
|
||||
|
||||
let ref types = Types::collect(errors, apis);
|
||||
|
@ -36,6 +36,7 @@ pub struct Parser<'a> {
|
||||
pub cxx_name: Option<&'a mut Option<ForeignName>>,
|
||||
pub rust_name: Option<&'a mut Option<Ident>>,
|
||||
pub variants_from_header: Option<&'a mut Option<Attribute>>,
|
||||
pub ignore_unrecognized: bool,
|
||||
|
||||
// Suppress clippy needless_update lint ("struct update has no effect, all
|
||||
// the fields in the struct have already been specified") when preemptively
|
||||
@ -172,8 +173,10 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cx.error(attr, "unsupported attribute");
|
||||
break;
|
||||
if !parser.ignore_unrecognized {
|
||||
cx.error(attr, "unsupported attribute");
|
||||
break;
|
||||
}
|
||||
}
|
||||
OtherAttrs(passthrough_attrs)
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::syntax::cfg::CfgExpr;
|
||||
use crate::syntax::namespace::Namespace;
|
||||
use quote::quote;
|
||||
use syn::parse::{Error, Parse, ParseStream, Result};
|
||||
@ -7,6 +8,7 @@ use syn::{
|
||||
};
|
||||
|
||||
pub struct Module {
|
||||
pub cfg: CfgExpr,
|
||||
pub namespace: Namespace,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub vis: Visibility,
|
||||
@ -36,6 +38,7 @@ pub struct ItemForeignMod {
|
||||
|
||||
impl Parse for Module {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let cfg = CfgExpr::Unconditional;
|
||||
let namespace = Namespace::ROOT;
|
||||
let mut attrs = input.call(Attribute::parse_outer)?;
|
||||
let vis: Visibility = input.parse()?;
|
||||
@ -62,6 +65,7 @@ impl Parse for Module {
|
||||
}
|
||||
|
||||
Ok(Module {
|
||||
cfg,
|
||||
namespace,
|
||||
attrs,
|
||||
vis,
|
||||
|
Loading…
Reference in New Issue
Block a user