Skip to content

Commit b0cd327

Browse files
committed
Track span information of include statements
1 parent e37ce2f commit b0cd327

File tree

4 files changed

+67
-13
lines changed

4 files changed

+67
-13
lines changed

gen/src/write.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::gen::{include, Opt};
33
use crate::syntax::atom::Atom::{self, *};
44
use crate::syntax::namespace::Namespace;
55
use crate::syntax::symbol::Symbol;
6-
use crate::syntax::{mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types, Var};
6+
use crate::syntax::{
7+
mangle, Api, Enum, ExternFn, ExternType, IncludeKind, Signature, Struct, Type, Types, Var,
8+
};
79
use proc_macro2::Ident;
810
use std::collections::HashMap;
911

@@ -24,7 +26,10 @@ pub(super) fn gen(
2426
out.include.extend(opt.include.clone());
2527
for api in apis {
2628
if let Api::Include(include) = api {
27-
out.include.insert(include);
29+
match include.kind {
30+
IncludeKind::Quoted => out.include.insert(&include.path),
31+
IncludeKind::Bracketed => out.include.insert(format!("<{}>", include.path)),
32+
}
2833
}
2934
}
3035

syntax/impls.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1-
use crate::syntax::{ExternFn, Impl, Receiver, Ref, Signature, Slice, Ty1, Type};
1+
use crate::syntax::{ExternFn, Impl, Include, Receiver, Ref, Signature, Slice, Ty1, Type};
22
use std::borrow::Borrow;
33
use std::hash::{Hash, Hasher};
44
use std::mem;
55
use std::ops::{Deref, DerefMut};
66

7+
impl PartialEq for Include {
8+
fn eq(&self, other: &Include) -> bool {
9+
let Include {
10+
path,
11+
kind,
12+
begin_span: _,
13+
end_span: _,
14+
} = self;
15+
let Include {
16+
path: path2,
17+
kind: kind2,
18+
begin_span: _,
19+
end_span: _,
20+
} = other;
21+
path == path2 && kind == kind2
22+
}
23+
}
24+
725
impl Deref for ExternFn {
826
type Target = Signature;
927

syntax/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub use self::parse::parse_items;
3434
pub use self::types::Types;
3535

3636
pub enum Api {
37-
Include(String),
37+
Include(Include),
3838
Struct(Struct),
3939
Enum(Enum),
4040
CxxType(ExternType),
@@ -45,6 +45,19 @@ pub enum Api {
4545
Impl(Impl),
4646
}
4747

48+
pub struct Include {
49+
pub path: String,
50+
pub kind: IncludeKind,
51+
pub begin_span: Span,
52+
pub end_span: Span,
53+
}
54+
55+
#[derive(Copy, Clone, PartialEq)]
56+
pub enum IncludeKind {
57+
Quoted, // #include "quoted/path/to"
58+
Bracketed, // #include <bracketed/path/to>
59+
}
60+
4861
pub struct ExternType {
4962
pub doc: Doc,
5063
pub type_token: Token![type],

syntax/parse.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ use crate::syntax::file::{Item, ItemForeignMod};
33
use crate::syntax::report::Errors;
44
use crate::syntax::Atom::*;
55
use crate::syntax::{
6-
attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Pair, Receiver, Ref, Signature,
7-
Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
6+
attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Include, IncludeKind, Lang, Pair,
7+
Receiver, Ref, Signature, Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
88
};
9-
use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
9+
use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
1010
use quote::{format_ident, quote, quote_spanned};
1111
use syn::parse::{ParseStream, Parser};
1212
use syn::punctuated::Punctuated;
@@ -471,17 +471,28 @@ fn parse_impl(imp: ItemImpl) -> Result<Api> {
471471
}))
472472
}
473473

474-
fn parse_include(input: ParseStream) -> Result<String> {
474+
fn parse_include(input: ParseStream) -> Result<Include> {
475475
if input.peek(LitStr) {
476-
return Ok(input.parse::<LitStr>()?.value());
476+
let lit: LitStr = input.parse()?;
477+
let span = lit.span();
478+
return Ok(Include {
479+
path: lit.value(),
480+
kind: IncludeKind::Quoted,
481+
begin_span: span,
482+
end_span: span,
483+
});
477484
}
478485

479486
if input.peek(Token![<]) {
480487
let mut path = String::new();
488+
let mut begin_span = None;
489+
let mut end_span = Span::call_site();
490+
481491
input.parse::<Token![<]>()?;
482-
path.push('<');
483492
while !input.is_empty() && !input.peek(Token![>]) {
484493
let token: TokenTree = input.parse()?;
494+
end_span = token.span();
495+
begin_span = Some(begin_span.unwrap_or(end_span));
485496
match token {
486497
TokenTree::Ident(token) => path += &token.to_string(),
487498
TokenTree::Literal(token)
@@ -495,9 +506,16 @@ fn parse_include(input: ParseStream) -> Result<String> {
495506
_ => return Err(Error::new(token.span(), "unexpected token in include path")),
496507
}
497508
}
498-
input.parse::<Token![>]>()?;
499-
path.push('>');
500-
return Ok(path);
509+
let rangle: Token![>] = input.parse()?;
510+
let begin_span =
511+
begin_span.ok_or_else(|| Error::new(rangle.span, "empty filename in #include"))?;
512+
513+
return Ok(Include {
514+
path,
515+
kind: IncludeKind::Bracketed,
516+
begin_span,
517+
end_span,
518+
});
501519
}
502520

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

0 commit comments

Comments
 (0)