Skip to content
This repository was archived by the owner on Oct 10, 2019. It is now read-only.

Commit 349a633

Browse files
committed
Use post-expansion to clean up modifier attributes
1 parent 812a298 commit 349a633

File tree

7 files changed

+39
-106
lines changed

7 files changed

+39
-106
lines changed

postgres-derive-codegen/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ keywords = ["database", "postgres", "postgresql", "sql"]
1010
exclude = ["test"]
1111

1212
[dependencies]
13-
syntex = "0.44"
14-
syntex_syntax = "0.44"
13+
syntex = "0.48"
14+
syntex_syntax = "0.48"
1515
postgres-derive-internals = { version = "0.2.0", path = "../postgres-derive-internals" }

postgres-derive-codegen/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ fn expand_inner(ctx: &mut ExtCtxt,
9595
match expand(&item) {
9696
Ok(source) => {
9797
let mut parser = parse::new_parser_from_source_str(&ctx.parse_sess,
98-
ctx.cfg.clone(),
9998
"<macro src>".to_owned(),
10099
source);
101100
while let Some(item) = parser.parse_item().unwrap() {

postgres-derive-internals/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ readme = "../README.md"
99
keywords = ["database", "postgres", "postgresql", "sql"]
1010

1111
[dependencies]
12-
syn = "0.9"
12+
syn = "0.10"
1313
quote = "0.3"

postgres-derive-internals/src/lib.rs

+1-88
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
#![recursion_limit = "256"]
2+
23
extern crate syn;
34
#[macro_use]
45
extern crate quote;
56

6-
use syn::{MacroInput, MetaItem, Body, VariantData};
7-
use quote::{Tokens, ToTokens};
8-
9-
use overrides::Overrides;
10-
117
mod accepts;
128
mod composites;
139
mod enums;
@@ -24,86 +20,3 @@ pub fn expand_derive_fromsql(source: &str) -> Result<String, String> {
2420
let input = try!(syn::parse_macro_input(source));
2521
fromsql::expand_derive_fromsql(&input)
2622
}
27-
28-
pub fn expand_derive(source: &str) -> Result<String, String> {
29-
let mut input = try!(syn::parse_macro_input(source));
30-
let (tosql, fromsql) = strip_derives(&mut input);
31-
32-
let tosql = if tosql {
33-
try!(tosql::expand_derive_tosql(&input))
34-
} else {
35-
"".to_owned()
36-
};
37-
let fromsql = if fromsql {
38-
try!(fromsql::expand_derive_fromsql(&input))
39-
} else {
40-
"".to_owned()
41-
};
42-
43-
strip_overrides(&mut input);
44-
45-
let mut tokens = Tokens::new();
46-
input.to_tokens(&mut tokens);
47-
48-
Ok(format!("{}{}{}", tokens, tosql, fromsql))
49-
}
50-
51-
fn strip_derives(input: &mut MacroInput) -> (bool, bool) {
52-
let mut tosql = false;
53-
let mut fromsql = false;
54-
55-
let mut other_attrs = vec![];
56-
for mut attr in input.attrs.drain(..) {
57-
{
58-
let mut items = match attr.value {
59-
MetaItem::List(ref name, ref mut items) if name == "derive" => items,
60-
_ => {
61-
other_attrs.push(attr);
62-
continue;
63-
}
64-
};
65-
66-
items.retain(|i| {
67-
match *i {
68-
MetaItem::Word(ref name) if name == "ToSql" => {
69-
tosql = true;
70-
false
71-
}
72-
MetaItem::Word(ref name) if name == "FromSql" => {
73-
fromsql = true;
74-
false
75-
}
76-
_ => true,
77-
}
78-
});
79-
80-
if items.is_empty() {
81-
continue;
82-
}
83-
}
84-
85-
other_attrs.push(attr);
86-
}
87-
88-
input.attrs = other_attrs;
89-
(tosql, fromsql)
90-
}
91-
92-
fn strip_overrides(input: &mut MacroInput) {
93-
Overrides::strip(&mut input.attrs);
94-
95-
match input.body {
96-
Body::Enum(ref mut variants) => {
97-
for variant in variants {
98-
Overrides::strip(&mut variant.attrs);
99-
}
100-
}
101-
Body::Struct(VariantData::Struct(ref mut fields)) |
102-
Body::Struct(VariantData::Tuple(ref mut fields)) => {
103-
for field in fields {
104-
Overrides::strip(&mut field.attrs);
105-
}
106-
}
107-
Body::Struct(VariantData::Unit) => {}
108-
}
109-
}

postgres-derive-internals/src/overrides.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use syn::{Attribute, MetaItem, Lit};
1+
use syn::{Attribute, MetaItem, NestedMetaItem, Lit};
22

33
pub struct Overrides {
44
pub name: Option<String>,
@@ -22,7 +22,7 @@ impl Overrides {
2222

2323
for item in list {
2424
match *item {
25-
MetaItem::NameValue(ref name, ref value) => {
25+
NestedMetaItem::MetaItem(MetaItem::NameValue(ref name, ref value)) => {
2626
if name != "name" {
2727
return Err(format!("unknown override `{}`", name));
2828
}
@@ -41,8 +41,4 @@ impl Overrides {
4141

4242
Ok(overrides)
4343
}
44-
45-
pub fn strip(attrs: &mut Vec<Attribute>) {
46-
attrs.retain(|a| a.name() != "postgres");
47-
}
4844
}

postgres-derive/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ test = false
1414

1515
[dependencies]
1616
postgres-derive-internals = { version = "0.2.0", path = "../postgres-derive-internals" }
17+
post-expansion = "0.2"
18+
syn = "0.10"
19+
quote = "0.3"
1720

1821
[dev-dependencies]
1922
postgres = "0.12"

postgres-derive/src/lib.rs

+30-8
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,45 @@
22

33
extern crate proc_macro;
44
extern crate postgres_derive_internals;
5+
#[macro_use]
6+
extern crate post_expansion;
7+
extern crate syn;
8+
extern crate quote;
59

610
use proc_macro::TokenStream;
11+
use quote::{ToTokens, Tokens};
12+
13+
register_post_expansion!(PostExpansion_postgres_derive);
714

815
#[proc_macro_derive(ToSql)]
916
pub fn derive_tosql(input: TokenStream) -> TokenStream {
10-
derive("ToSql", input)
17+
derive(input, postgres_derive_internals::expand_derive_tosql)
1118
}
1219

1320
#[proc_macro_derive(FromSql)]
1421
pub fn derive_fromsql(input: TokenStream) -> TokenStream {
15-
derive("FromSql", input)
22+
derive(input, postgres_derive_internals::expand_derive_fromsql)
1623
}
1724

18-
fn derive(trait_: &str, input: TokenStream) -> TokenStream {
19-
let input = format!("#[derive({})] {}", trait_, input);
20-
match postgres_derive_internals::expand_derive(&input) {
21-
Ok(expanded) => expanded.parse().unwrap(),
22-
Err(err) => panic!(err),
23-
}
25+
fn derive(input: TokenStream, expand: fn(&str) -> Result<String, String>) -> TokenStream {
26+
let source = input.to_string();
27+
28+
let decl = expand_decl(&source);
29+
30+
let impl_ = match expand(&source) {
31+
Ok(impl_) => impl_,
32+
Err(e) => panic!("{}", e),
33+
};
34+
35+
let expanded = format!("{}\n{}", decl, impl_);
36+
expanded.parse().unwrap()
37+
}
38+
39+
fn expand_decl(source: &str) -> String {
40+
let ast = syn::parse_macro_input(source).unwrap();
41+
let stripped = post_expansion::strip_attrs_later(ast, &["postgres"], "postgres_derive");
42+
43+
let mut tokens = Tokens::new();
44+
stripped.to_tokens(&mut tokens);
45+
tokens.to_string()
2446
}

0 commit comments

Comments
 (0)