os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap());
}
let cfg = syntax::ext::expand::ExpansionConfig {
- deriving_hash_type_parameter: sess.features.borrow().default_type_params,
crate_name: crate_name.to_string(),
+ deriving_hash_type_parameter: sess.features.borrow().default_type_params,
+ enable_quotes: sess.features.borrow().quote,
};
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
cfg,
/// The base map of methods for expanding syntax extension
/// AST nodes into full ASTs
-fn initial_syntax_expander_table() -> SyntaxEnv {
+fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
NormalTT(box f, None)
syntax_expanders.insert(intern("deriving"),
Decorator(box ext::deriving::expand_meta_deriving));
- // Quasi-quoting expanders
- syntax_expanders.insert(intern("quote_tokens"),
- builtin_normal_expander(
- ext::quote::expand_quote_tokens));
- syntax_expanders.insert(intern("quote_expr"),
- builtin_normal_expander(
- ext::quote::expand_quote_expr));
- syntax_expanders.insert(intern("quote_ty"),
- builtin_normal_expander(
- ext::quote::expand_quote_ty));
- syntax_expanders.insert(intern("quote_method"),
- builtin_normal_expander(
- ext::quote::expand_quote_method));
- syntax_expanders.insert(intern("quote_item"),
- builtin_normal_expander(
- ext::quote::expand_quote_item));
- syntax_expanders.insert(intern("quote_pat"),
- builtin_normal_expander(
- ext::quote::expand_quote_pat));
- syntax_expanders.insert(intern("quote_arm"),
- builtin_normal_expander(
- ext::quote::expand_quote_arm));
- syntax_expanders.insert(intern("quote_stmt"),
- builtin_normal_expander(
- ext::quote::expand_quote_stmt));
+ if ecfg.enable_quotes {
+ // Quasi-quoting expanders
+ syntax_expanders.insert(intern("quote_tokens"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_tokens));
+ syntax_expanders.insert(intern("quote_expr"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_expr));
+ syntax_expanders.insert(intern("quote_ty"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_ty));
+ syntax_expanders.insert(intern("quote_method"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_method));
+ syntax_expanders.insert(intern("quote_item"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_item));
+ syntax_expanders.insert(intern("quote_pat"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_pat));
+ syntax_expanders.insert(intern("quote_arm"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_arm));
+ syntax_expanders.insert(intern("quote_stmt"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_stmt));
+ }
syntax_expanders.insert(intern("line"),
builtin_normal_expander(
impl<'a> ExtCtxt<'a> {
pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
+ let env = initial_syntax_expander_table(&ecfg);
ExtCtxt {
parse_sess: parse_sess,
cfg: cfg,
ecfg: ecfg,
trace_mac: false,
exported_macros: Vec::new(),
- syntax_env: initial_syntax_expander_table(),
+ syntax_env: env,
}
}
}
pub struct ExpansionConfig {
- pub deriving_hash_type_parameter: bool,
pub crate_name: String,
+ pub deriving_hash_type_parameter: bool,
+ pub enable_quotes: bool,
+}
+
+impl ExpansionConfig {
+ pub fn default(crate_name: String) -> ExpansionConfig {
+ ExpansionConfig {
+ crate_name: crate_name,
+ deriving_hash_type_parameter: false,
+ enable_quotes: false,
+ }
+ }
}
pub struct ExportedMacros {
#[cfg(test)]
mod test {
use super::{pattern_bindings, expand_crate, contains_macro_escape};
- use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
+ use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
use ast;
use ast::{Attribute_, AttrOuter, MetaWord, Name};
use attr;
// these following tests are quite fragile, in that they don't test what
// *kind* of failure occurs.
+ fn test_ecfg() -> ExpansionConfig {
+ ExpansionConfig::default("test".to_string())
+ }
+
// make sure that macros can't escape fns
#[should_fail]
#[test] fn macros_cant_escape_fns_test () {
src,
Vec::new(), &sess);
// should fail:
- let cfg = ::syntax::ext::expand::ExpansionConfig {
- deriving_hash_type_parameter: false,
- crate_name: "test".to_string(),
- };
- expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
+ expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
}
// make sure that macros can't escape modules
"<test>".to_string(),
src,
Vec::new(), &sess);
- let cfg = ::syntax::ext::expand::ExpansionConfig {
- deriving_hash_type_parameter: false,
- crate_name: "test".to_string(),
- };
- expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
+ expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
}
// macro_escape modules should allow macros to escape
"<test>".to_string(),
src,
Vec::new(), &sess);
- let cfg = ::syntax::ext::expand::ExpansionConfig {
- deriving_hash_type_parameter: false,
- crate_name: "test".to_string(),
- };
- expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
+ expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast);
}
#[test] fn test_contains_flatten (){
let ps = parse::new_parse_sess();
let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
// the cfg argument actually does matter, here...
- let cfg = ::syntax::ext::expand::ExpansionConfig {
- deriving_hash_type_parameter: false,
- crate_name: "test".to_string(),
- };
- expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
+ expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast)
}
// find the pat_ident paths in a crate
pub rustc_diagnostic_macros: bool,
pub import_shadowing: bool,
pub visible_private_types: bool,
+ pub quote: bool,
}
impl Features {
rustc_diagnostic_macros: false,
import_shadowing: false,
visible_private_types: false,
+ quote: false,
}
}
}
fn visit_mac(&mut self, macro: &ast::Mac) {
let ast::MacInvocTT(ref path, _, _) = macro.node;
let id = path.segments.last().unwrap().identifier;
- let quotes = ["quote_tokens", "quote_expr", "quote_ty",
- "quote_item", "quote_pat", "quote_stmt"];
- let msg = " is not stable enough for use and are subject to change";
-
if id == token::str_to_ident("macro_rules") {
self.gate_feature("macro_rules", path.span, "macro definitions are \
self.gate_feature("concat_idents", path.span, "`concat_idents` is not \
stable enough for use and is subject to change");
}
-
- else {
- for "e in quotes.iter() {
- if id == token::str_to_ident(quote) {
- self.gate_feature("quote",
- path.span,
- format!("{}{}", quote, msg).as_slice());
- }
- }
- }
}
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
import_shadowing: cx.has_feature("import_shadowing"),
visible_private_types: cx.has_feature("visible_private_types"),
+ quote: cx.has_feature("quote"),
},
unknown_features)
}
sess: sess,
span_diagnostic: sd,
ext_cx: ExtCtxt::new(sess, cfg.clone(),
- ExpansionConfig {
- deriving_hash_type_parameter: false,
- crate_name: "test".to_string(),
- }),
+ ExpansionConfig::default("test".to_string())),
path: Vec::new(),
testfns: Vec::new(),
reexport_test_harness_main: reexport_test_harness_main,
--- /dev/null
+// Copyright 2014 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.
+
+#![feature(macro_rules)]
+
+macro_rules! quote_tokens ( () => (()) )
+
+pub fn main() {
+ quote_tokens!();
+}