about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2015-05-01 15:49:05 +0530
committerManish Goregaokar <manishsmail@gmail.com>2015-05-01 15:49:05 +0530
commit4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e (patch)
tree08a1b6374a942f44b67c1ef8565e43ebaf4d3ecc /src/test
parentede7a6dc8ff5455f9d0d39a90e6d11e9a374e93b (diff)
downloadrust-4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e.tar.gz
rust-4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e.zip
Add test for custom deriving plugins which rely on field attributes
Diffstat (limited to 'src/test')
-rw-r--r--src/test/auxiliary/custom_derive_plugin_attr.rs86
-rw-r--r--src/test/run-pass-fulldeps/derive-totalsum-attr.rs74
2 files changed, 160 insertions, 0 deletions
diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/auxiliary/custom_derive_plugin_attr.rs
new file mode 100644
index 00000000000..631645ec0c0
--- /dev/null
+++ b/src/test/auxiliary/custom_derive_plugin_attr.rs
@@ -0,0 +1,86 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax)]
+#![feature(rustc_private)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::ast;
+use syntax::attr::AttrMetaMethods;
+use syntax::codemap::Span;
+use syntax::ext::base::{Decorator, ExtCtxt};
+use syntax::ext::build::AstBuilder;
+use syntax::ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure};
+use syntax::ext::deriving::generic::{Substructure, Struct, EnumMatching};
+use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self};
+use syntax::parse::token;
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_syntax_extension(
+        token::intern("derive_TotalSum"),
+        Decorator(box expand));
+}
+
+fn expand(cx: &mut ExtCtxt,
+          span: Span,
+          mitem: &ast::MetaItem,
+          item: &ast::Item,
+          push: &mut FnMut(P<ast::Item>)) {
+    let trait_def = TraitDef {
+        span: span,
+        attributes: vec![],
+        path: Path::new(vec!["TotalSum"]),
+        additional_bounds: vec![],
+        generics: LifetimeBounds::empty(),
+        associated_types: vec![],
+        methods: vec![
+            MethodDef {
+                name: "total_sum",
+                generics: LifetimeBounds::empty(),
+                explicit_self: borrowed_explicit_self(),
+                args: vec![],
+                ret_ty: Literal(Path::new_local("isize")),
+                attributes: vec![],
+                combine_substructure: combine_substructure(Box::new(totalsum_substructure)),
+            },
+        ],
+    };
+
+    trait_def.expand(cx, mitem, item, push)
+}
+
+// Mostly copied from syntax::ext::deriving::hash
+/// Defines how the implementation for `trace()` is to be generated
+fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<ast::Expr> {
+    let fields = match *substr.fields {
+        Struct(ref fs) | EnumMatching(_, _, ref fs) => fs,
+        _ => cx.span_bug(trait_span, "impossible substructure")
+    };
+
+    fields.iter().fold(cx.expr_int(trait_span, 0), |acc, ref item| {
+        if item.attrs.iter().find(|a| a.check_name("ignore")).is_some() {
+            acc
+        } else {
+            cx.expr_binary(item.span, ast::BiAdd, acc,
+                           cx.expr_method_call(item.span,
+                                               item.self_.clone(),
+                                               substr.method_ident,
+                                               Vec::new()))
+        }
+    })
+}
diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
new file mode 100644
index 00000000000..ef5198b9ae0
--- /dev/null
+++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
@@ -0,0 +1,74 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:custom_derive_plugin_attr.rs
+// ignore-stage1
+
+#![feature(plugin, custom_derive, custom_attribute)]
+#![plugin(custom_derive_plugin_attr)]
+
+trait TotalSum {
+    fn total_sum(&self) -> isize;
+}
+
+impl TotalSum for isize {
+    fn total_sum(&self) -> isize {
+        *self
+    }
+}
+
+struct Seven;
+
+impl TotalSum for Seven {
+    fn total_sum(&self) -> isize {
+        7
+    }
+}
+
+#[derive(TotalSum)]
+struct Foo {
+    seven: Seven,
+    bar: Bar,
+    baz: isize,
+    #[ignore]
+    nan: NaN,
+}
+
+#[derive(TotalSum)]
+struct Bar {
+    quux: isize,
+    bleh: isize,
+    #[ignore]
+    nan: NaN2
+}
+
+struct NaN;
+
+impl TotalSum for NaN {
+    fn total_sum(&self) -> isize {
+        panic!();
+    }
+}
+
+struct NaN2;
+
+pub fn main() {
+    let v = Foo {
+        seven: Seven,
+        bar: Bar {
+            quux: 9,
+            bleh: 3,
+            nan: NaN2
+        },
+        baz: 80,
+        nan: NaN
+    };
+    assert_eq!(v.total_sum(), 99);
+}