Skip to content

Commit

Permalink
Merge pull request #201 from dtolnay/include
Browse files Browse the repository at this point in the history
Parse include!(<path/to/bracketed>)
  • Loading branch information
dtolnay authored May 12, 2020
2 parents 8918451 + cf96664 commit 14db1e2
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 9 deletions.
4 changes: 2 additions & 2 deletions gen/src/include.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ impl Includes {
Includes::default()
}

pub fn insert(&mut self, include: String) {
self.custom.push(include);
pub fn insert(&mut self, include: impl AsRef<str>) {
self.custom.push(include.as_ref().to_owned());
}
}

Expand Down
2 changes: 1 addition & 1 deletion gen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(super) fn gen(
out.include.extend(opt.include);
for api in apis {
if let Api::Include(include) = api {
out.include.insert(include.value());
out.include.insert(include);
}
}

Expand Down
4 changes: 2 additions & 2 deletions syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use self::parse::kw;
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::token::{Brace, Bracket, Paren};
use syn::{Expr, Lifetime, LitStr, Token, Type as RustType};
use syn::{Expr, Lifetime, Token, Type as RustType};

pub use self::atom::Atom;
pub use self::derive::Derive;
Expand All @@ -32,7 +32,7 @@ pub use self::parse::parse_items;
pub use self::types::Types;

pub enum Api {
Include(LitStr),
Include(String),
Struct(Struct),
Enum(Enum),
CxxType(ExternType),
Expand Down
40 changes: 36 additions & 4 deletions syntax/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::syntax::{
attrs, error, Api, Doc, Enum, ExternFn, ExternType, Lang, Receiver, Ref, Signature, Slice,
Struct, Ty1, Type, TypeAlias, Var, Variant,
};
use proc_macro2::TokenStream;
use proc_macro2::{TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned};
use syn::parse::{ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::{
Abi, Attribute, Error, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType,
GenericArgument, Ident, Item, ItemEnum, ItemForeignMod, ItemStruct, Pat, PathArguments, Result,
ReturnType, Token, Type as RustType, TypeBareFn, TypePath, TypeReference, TypeSlice,
GenericArgument, Ident, Item, ItemEnum, ItemForeignMod, ItemStruct, LitStr, Pat, PathArguments,
Result, ReturnType, Token, Type as RustType, TypeBareFn, TypePath, TypeReference, TypeSlice,
};

pub mod kw {
Expand Down Expand Up @@ -187,7 +187,7 @@ fn parse_foreign_mod(cx: &mut Errors, foreign_mod: ItemForeignMod, out: &mut Vec
Err(err) => cx.push(err),
},
ForeignItem::Macro(foreign) if foreign.mac.path.is_ident("include") => {
match foreign.mac.parse_body() {
match foreign.mac.parse_body_with(parse_include) {
Ok(include) => items.push(Api::Include(include)),
Err(err) => cx.push(err),
}
Expand Down Expand Up @@ -389,6 +389,38 @@ fn parse_extern_verbatim(cx: &mut Errors, tokens: &TokenStream, lang: Lang) -> R
}
}

fn parse_include(input: ParseStream) -> Result<String> {
if input.peek(LitStr) {
return Ok(input.parse::<LitStr>()?.value());
}

if input.peek(Token![<]) {
let mut path = String::new();
input.parse::<Token![<]>()?;
path.push('<');
while !input.is_empty() && !input.peek(Token![>]) {
let token: TokenTree = input.parse()?;
match token {
TokenTree::Ident(token) => path += &token.to_string(),
TokenTree::Literal(token)
if token
.to_string()
.starts_with(|ch: char| ch.is_ascii_digit()) =>
{
path += &token.to_string();
}
TokenTree::Punct(token) => path.push(token.as_char()),
_ => return Err(Error::new(token.span(), "unexpected token in include path")),
}
}
input.parse::<Token![>]>()?;
path.push('>');
return Ok(path);
}

Err(input.error("expected \"quoted/path/to\" or <bracketed/path/to>"))
}

fn parse_type(ty: &RustType) -> Result<Type> {
match ty {
RustType::Reference(ty) => parse_type_reference(ty),
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/include.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#[cxx::bridge]
mod ffi {
extern "C" {
include!("path/to" what);
include!(<path/to> what);
include!(<path/to);
include!(<path[to]>);
include!(...);
}
}

fn main() {}
29 changes: 29 additions & 0 deletions tests/ui/include.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error: unexpected token
--> $DIR/include.rs:4:28
|
4 | include!("path/to" what);
| ^^^^

error: unexpected token
--> $DIR/include.rs:5:28
|
5 | include!(<path/to> what);
| ^^^^

error: expected `>`
--> $DIR/include.rs:6:17
|
6 | include!(<path/to);
| ^^^^^^^^^^

error: unexpected token in include path
--> $DIR/include.rs:7:23
|
7 | include!(<path[to]>);
| ^^^^

error: expected "quoted/path/to" or <bracketed/path/to>
--> $DIR/include.rs:8:18
|
8 | include!(...);
| ^^^

0 comments on commit 14db1e2

Please sign in to comment.