auto merge of #14554 : kmcallister/rust/plugin_registrar, r=cmr
This implements the design in rust-lang/rfcs#86. It shouldn't be merged until that RFC is accepted, but it would be great if somebody has time to review the code before then.
This commit is contained in:
commit
0ea7aa30cc
|
@ -83,8 +83,8 @@ DEPS_uuid := std serialize
|
||||||
DEPS_sync := std alloc
|
DEPS_sync := std alloc
|
||||||
DEPS_getopts := std
|
DEPS_getopts := std
|
||||||
DEPS_collections := core alloc
|
DEPS_collections := core alloc
|
||||||
DEPS_fourcc := syntax std
|
DEPS_fourcc := rustc syntax std
|
||||||
DEPS_hexfloat := syntax std
|
DEPS_hexfloat := rustc syntax std
|
||||||
DEPS_num := std
|
DEPS_num := std
|
||||||
DEPS_test := std getopts serialize term time regex native:rust_test_helpers
|
DEPS_test := std getopts serialize term time regex native:rust_test_helpers
|
||||||
DEPS_time := std serialize sync
|
DEPS_time := std serialize sync
|
||||||
|
@ -92,7 +92,7 @@ DEPS_rand := core
|
||||||
DEPS_url := std
|
DEPS_url := std
|
||||||
DEPS_log := std sync
|
DEPS_log := std sync
|
||||||
DEPS_regex := std
|
DEPS_regex := std
|
||||||
DEPS_regex_macros = syntax std regex
|
DEPS_regex_macros = rustc syntax std regex
|
||||||
DEPS_fmt_macros = std
|
DEPS_fmt_macros = std
|
||||||
|
|
||||||
TOOL_DEPS_compiletest := test green rustuv getopts
|
TOOL_DEPS_compiletest := test green rustuv getopts
|
||||||
|
|
|
@ -18,11 +18,17 @@
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
#[phase(link, syntax)]
|
|
||||||
extern crate log;
|
|
||||||
extern crate green;
|
extern crate green;
|
||||||
extern crate rustuv;
|
extern crate rustuv;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
#[phase(syntax, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
|
@ -1819,9 +1819,8 @@ type int8_t = i8;
|
||||||
|
|
||||||
### Function-only attributes
|
### Function-only attributes
|
||||||
|
|
||||||
- `macro_registrar` - when using loadable syntax extensions, mark this
|
- `plugin_registrar` - mark this function as the registration point for
|
||||||
function as the registration point for the current crate's syntax
|
compiler plugins, such as loadable syntax extensions.
|
||||||
extensions.
|
|
||||||
- `main` - indicates that this function should be passed to the entry point,
|
- `main` - indicates that this function should be passed to the entry point,
|
||||||
rather than the function in the crate root named `main`.
|
rather than the function in the crate root named `main`.
|
||||||
- `start` - indicates that this function should be used as the entry point,
|
- `start` - indicates that this function should be used as the entry point,
|
||||||
|
@ -4098,7 +4097,7 @@ that demonstrates all four of them:
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
error!("This is an error log")
|
error!("This is an error log")
|
||||||
|
|
|
@ -70,8 +70,14 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,8 +86,10 @@ extern crate libc;
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] extern crate sync;
|
#[cfg(test)] extern crate sync;
|
||||||
#[cfg(test)] extern crate native;
|
#[cfg(test)] extern crate native;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate std;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
// Heaps provided for low-level allocation strategies
|
// Heaps provided for low-level allocation strategies
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,24 @@
|
||||||
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
|
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[phase(syntax, link)] extern crate core;
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
#[phase(syntax, link)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
#[cfg(test)] extern crate native;
|
#[cfg(test)] extern crate native;
|
||||||
#[cfg(test)] extern crate test;
|
#[cfg(test)] extern crate test;
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate std;
|
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
|
||||||
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ Simple [DEFLATE][def]-based compression. This is a wrapper around the
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
|
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ to be `big`, i.e. left-to-right order. It returns a u32.
|
||||||
To load the extension and use it:
|
To load the extension and use it:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -48,29 +48,25 @@ fn main() {
|
||||||
html_root_url = "http://doc.rust-lang.org/")]
|
html_root_url = "http://doc.rust-lang.org/")]
|
||||||
|
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
#![feature(macro_registrar, managed_boxes)]
|
#![feature(plugin_registrar, managed_boxes)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate rustc;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::Name;
|
|
||||||
use syntax::attr::contains;
|
use syntax::attr::contains;
|
||||||
use syntax::codemap::{Span, mk_sp};
|
use syntax::codemap::{Span, mk_sp};
|
||||||
use syntax::ext::base;
|
use syntax::ext::base;
|
||||||
use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr};
|
use syntax::ext::base::{ExtCtxt, MacExpr};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
register(token::intern("fourcc"),
|
reg.register_macro("fourcc", expand_syntax_ext);
|
||||||
NormalTT(box BasicMacroExpander {
|
|
||||||
expander: expand_syntax_ext,
|
|
||||||
span: None,
|
|
||||||
},
|
|
||||||
None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||||
|
|
|
@ -91,7 +91,8 @@
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
|
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
use std::result::{Err, Ok};
|
use std::result::{Err, Ok};
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! #![feature(phase)]
|
//! #![feature(phase)]
|
||||||
//! #[phase(syntax)] extern crate green;
|
//! #[phase(plugin)] extern crate green;
|
||||||
//!
|
//!
|
||||||
//! green_start!(main)
|
//! green_start!(main)
|
||||||
//!
|
//!
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
#![allow(visible_private_types)]
|
#![allow(visible_private_types)]
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
|
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||||
#[cfg(test)] extern crate rustuv;
|
#[cfg(test)] extern crate rustuv;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -249,7 +249,7 @@ pub mod task;
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax)] extern crate green;
|
/// #[phase(plugin)] extern crate green;
|
||||||
///
|
///
|
||||||
/// green_start!(main)
|
/// green_start!(main)
|
||||||
///
|
///
|
||||||
|
|
|
@ -21,7 +21,7 @@ literal.
|
||||||
To load the extension and use it:
|
To load the extension and use it:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate hexfloat;
|
extern crate hexfloat;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -45,27 +45,23 @@ fn main() {
|
||||||
html_root_url = "http://doc.rust-lang.org/")]
|
html_root_url = "http://doc.rust-lang.org/")]
|
||||||
|
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
#![feature(macro_registrar, managed_boxes)]
|
#![feature(plugin_registrar, managed_boxes)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate rustc;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::Name;
|
|
||||||
use syntax::codemap::{Span, mk_sp};
|
use syntax::codemap::{Span, mk_sp};
|
||||||
use syntax::ext::base;
|
use syntax::ext::base;
|
||||||
use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr};
|
use syntax::ext::base::{ExtCtxt, MacExpr};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
register(token::intern("hexfloat"),
|
reg.register_macro("hexfloat", expand_syntax_ext);
|
||||||
NormalTT(box BasicMacroExpander {
|
|
||||||
expander: expand_syntax_ext,
|
|
||||||
span: None,
|
|
||||||
},
|
|
||||||
None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the literal is valid (as LLVM expects),
|
//Check if the literal is valid (as LLVM expects),
|
||||||
|
|
|
@ -16,7 +16,7 @@ Utilities for program-wide and customizable logging
|
||||||
|
|
||||||
```
|
```
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
debug!("this is a debug {}", "message");
|
debug!("this is a debug {}", "message");
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// log!(log::DEBUG, "this is a debug message");
|
/// log!(log::DEBUG, "this is a debug message");
|
||||||
|
@ -51,7 +51,7 @@ macro_rules! log(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// # let error = 3;
|
/// # let error = 3;
|
||||||
|
@ -69,7 +69,7 @@ macro_rules! error(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// # let code = 3;
|
/// # let code = 3;
|
||||||
|
@ -87,7 +87,7 @@ macro_rules! warn(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// # let ret = 3;
|
/// # let ret = 3;
|
||||||
|
@ -107,7 +107,7 @@ macro_rules! info(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// debug!("x = {x}, y = {y}", x=10, y=20);
|
/// debug!("x = {x}, y = {y}", x=10, y=20);
|
||||||
|
@ -124,7 +124,7 @@ macro_rules! debug(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// #[phase(syntax, link)] extern crate log;
|
/// #[phase(plugin, link)] extern crate log;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// # struct Point { x: int, y: int }
|
/// # struct Point { x: int, y: int }
|
||||||
|
|
|
@ -28,13 +28,28 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![experimental]
|
#![experimental]
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
|
#[cfg(test, stage0)]
|
||||||
|
#[phase(syntax, link)] extern crate std;
|
||||||
|
|
||||||
|
#[cfg(test, stage0)]
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
|
#[cfg(test, not(stage0))]
|
||||||
|
#[phase(plugin, link)] extern crate std;
|
||||||
|
|
||||||
|
#[cfg(test, not(stage0))]
|
||||||
|
#[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
#[cfg(test)] extern crate native;
|
#[cfg(test)] extern crate native;
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate std;
|
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
|
||||||
|
|
||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! #![feature(phase)]
|
//! #![feature(phase)]
|
||||||
//! #[phase(syntax)]
|
//! #[phase(plugin)]
|
||||||
//! extern crate regex_macros;
|
//! extern crate regex_macros;
|
||||||
//! extern crate regex;
|
//! extern crate regex;
|
||||||
//!
|
//!
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(phase)]
|
//! # #![feature(phase)]
|
||||||
//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! let re = regex!(r"(\d{4})-(\d{2})-(\d{2})");
|
//! let re = regex!(r"(\d{4})-(\d{2})-(\d{2})");
|
||||||
//! let text = "2012-03-14, 2013-01-01 and 2014-07-05";
|
//! let text = "2012-03-14, 2013-01-01 and 2014-07-05";
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(phase)]
|
//! # #![feature(phase)]
|
||||||
//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! let re = regex!(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})");
|
//! let re = regex!(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})");
|
||||||
//! let before = "2012-03-14, 2013-01-01 and 2014-07-05";
|
//! let before = "2012-03-14, 2013-01-01 and 2014-07-05";
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(phase)]
|
//! # #![feature(phase)]
|
||||||
//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! let re = regex!(r"(?i)Δ+");
|
//! let re = regex!(r"(?i)Δ+");
|
||||||
//! assert_eq!(re.find("ΔδΔ"), Some((0, 6)));
|
//! assert_eq!(re.find("ΔδΔ"), Some((0, 6)));
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(phase)]
|
//! # #![feature(phase)]
|
||||||
//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! let re = regex!(r"[\pN\p{Greek}\p{Cherokee}]+");
|
//! let re = regex!(r"[\pN\p{Greek}\p{Cherokee}]+");
|
||||||
//! assert_eq!(re.find("abcΔᎠβⅠᏴγδⅡxyz"), Some((3, 23)));
|
//! assert_eq!(re.find("abcΔᎠβⅠᏴγδⅡxyz"), Some((3, 23)));
|
||||||
|
@ -278,7 +278,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(phase)]
|
//! # #![feature(phase)]
|
||||||
//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! let re = regex!(r"(?i)a+(?-i)b+");
|
//! let re = regex!(r"(?i)a+(?-i)b+");
|
||||||
//! let cap = re.captures("AaAaAbbBBBb").unwrap();
|
//! let cap = re.captures("AaAaAbbBBBb").unwrap();
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(phase)]
|
/// #![feature(phase)]
|
||||||
/// extern crate regex;
|
/// extern crate regex;
|
||||||
/// #[phase(syntax)] extern crate regex_macros;
|
/// #[phase(plugin)] extern crate regex_macros;
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let re = regex!(r"\d+");
|
/// let re = regex!(r"\d+");
|
||||||
|
@ -172,7 +172,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let text = "I categorically deny having triskaidekaphobia.";
|
/// let text = "I categorically deny having triskaidekaphobia.";
|
||||||
/// let matched = regex!(r"\b\w{13}\b").is_match(text);
|
/// let matched = regex!(r"\b\w{13}\b").is_match(text);
|
||||||
|
@ -197,7 +197,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let text = "I categorically deny having triskaidekaphobia.";
|
/// let text = "I categorically deny having triskaidekaphobia.";
|
||||||
/// let pos = regex!(r"\b\w{13}\b").find(text);
|
/// let pos = regex!(r"\b\w{13}\b").find(text);
|
||||||
|
@ -224,7 +224,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let text = "Retroactively relinquishing remunerations is reprehensible.";
|
/// let text = "Retroactively relinquishing remunerations is reprehensible.";
|
||||||
/// for pos in regex!(r"\b\w{13}\b").find_iter(text) {
|
/// for pos in regex!(r"\b\w{13}\b").find_iter(text) {
|
||||||
|
@ -263,7 +263,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"'([^']+)'\s+\((\d{4})\)");
|
/// let re = regex!(r"'([^']+)'\s+\((\d{4})\)");
|
||||||
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
|
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
|
||||||
|
@ -281,7 +281,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
|
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
|
||||||
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
|
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
|
||||||
|
@ -314,7 +314,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
|
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
|
||||||
/// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
|
/// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
|
||||||
|
@ -350,7 +350,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"[ \t]+");
|
/// let re = regex!(r"[ \t]+");
|
||||||
/// let fields: Vec<&str> = re.split("a b \t c\td e").collect();
|
/// let fields: Vec<&str> = re.split("a b \t c\td e").collect();
|
||||||
|
@ -380,7 +380,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"\W+");
|
/// let re = regex!(r"\W+");
|
||||||
/// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
|
/// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
|
||||||
|
@ -410,7 +410,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!("[^01]+");
|
/// let re = regex!("[^01]+");
|
||||||
/// assert_eq!(re.replace("1078910", "").as_slice(), "1010");
|
/// assert_eq!(re.replace("1078910", "").as_slice(), "1010");
|
||||||
|
@ -424,7 +424,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # use regex::Captures; fn main() {
|
/// # use regex::Captures; fn main() {
|
||||||
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
|
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
|
||||||
/// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
|
/// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
|
||||||
|
@ -441,7 +441,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let re = regex!(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)");
|
/// let re = regex!(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)");
|
||||||
/// let result = re.replace("Springsteen, Bruce", "$first $last");
|
/// let result = re.replace("Springsteen, Bruce", "$first $last");
|
||||||
|
@ -458,7 +458,7 @@ impl Regex {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(phase)]
|
/// # #![feature(phase)]
|
||||||
/// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
|
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// use regex::NoExpand;
|
/// use regex::NoExpand;
|
||||||
///
|
///
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[cfg(not(stage1))]
|
#[cfg(not(stage1))]
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate regex_macros;
|
extern crate regex_macros;
|
||||||
|
|
||||||
#[cfg(not(stage1))]
|
#[cfg(not(stage1))]
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||||
html_root_url = "http://doc.rust-lang.org/")]
|
html_root_url = "http://doc.rust-lang.org/")]
|
||||||
|
|
||||||
#![feature(macro_registrar, managed_boxes, quote)]
|
#![feature(plugin_registrar, managed_boxes, quote)]
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate rustc;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::ext::base::{
|
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
|
||||||
SyntaxExtension, ExtCtxt, MacResult, MacExpr, DummyResult,
|
|
||||||
NormalTT, BasicMacroExpander,
|
|
||||||
};
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
|
|
||||||
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use regex::native::{
|
use regex::native::{
|
||||||
OneChar, CharClass, Any, Save, Jump, Split,
|
OneChar, CharClass, Any, Save, Jump, Split,
|
||||||
|
@ -46,11 +46,10 @@ use regex::native::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// For the `regex!` syntax extension. Do not use.
|
/// For the `regex!` syntax extension. Do not use.
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn macro_registrar(register: |ast::Name, SyntaxExtension|) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
let expander = box BasicMacroExpander { expander: native, span: None };
|
reg.register_macro("regex", native);
|
||||||
register(token::intern("regex"), NormalTT(expander, None))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates specialized code for the Pike VM for a particular regular
|
/// Generates specialized code for the Pike VM for a particular regular
|
||||||
|
|
|
@ -18,12 +18,14 @@ use front;
|
||||||
use lib::llvm::{ContextRef, ModuleRef};
|
use lib::llvm::{ContextRef, ModuleRef};
|
||||||
use metadata::common::LinkMeta;
|
use metadata::common::LinkMeta;
|
||||||
use metadata::creader;
|
use metadata::creader;
|
||||||
use metadata::creader::Loader;
|
|
||||||
use middle::cfg;
|
use middle::cfg;
|
||||||
use middle::cfg::graphviz::LabelledCFG;
|
use middle::cfg::graphviz::LabelledCFG;
|
||||||
use middle::{trans, freevars, kind, ty, typeck, lint, reachable};
|
use middle::{trans, freevars, kind, ty, typeck, lint, reachable};
|
||||||
use middle::dependency_format;
|
use middle::dependency_format;
|
||||||
use middle;
|
use middle;
|
||||||
|
use plugin::load::Plugins;
|
||||||
|
use plugin::registry::Registry;
|
||||||
|
use plugin;
|
||||||
use util::common::time;
|
use util::common::time;
|
||||||
use util::ppaux;
|
use util::ppaux;
|
||||||
use util::nodemap::{NodeSet};
|
use util::nodemap::{NodeSet};
|
||||||
|
@ -39,7 +41,6 @@ use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::attr::{AttrMetaMethods};
|
use syntax::attr::{AttrMetaMethods};
|
||||||
use syntax::crateid::CrateId;
|
use syntax::crateid::CrateId;
|
||||||
use syntax::ext::base::CrateLoader;
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::print::{pp, pprust};
|
use syntax::print::{pp, pprust};
|
||||||
|
@ -75,11 +76,10 @@ pub fn compile_input(sess: Session,
|
||||||
output,
|
output,
|
||||||
krate.attrs.as_slice(),
|
krate.attrs.as_slice(),
|
||||||
&sess);
|
&sess);
|
||||||
let loader = &mut Loader::new(&sess);
|
|
||||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||||
outputs.out_filestem.as_slice());
|
outputs.out_filestem.as_slice());
|
||||||
let (expanded_crate, ast_map) =
|
let (expanded_crate, ast_map) =
|
||||||
phase_2_configure_and_expand(&sess, loader, krate, &id);
|
phase_2_configure_and_expand(&sess, krate, &id);
|
||||||
(outputs, expanded_crate, ast_map)
|
(outputs, expanded_crate, ast_map)
|
||||||
};
|
};
|
||||||
write_out_deps(&sess, input, &outputs, &expanded_crate);
|
write_out_deps(&sess, input, &outputs, &expanded_crate);
|
||||||
|
@ -172,7 +172,6 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
|
||||||
/// harness if one is to be provided and injection of a dependency on the
|
/// harness if one is to be provided and injection of a dependency on the
|
||||||
/// standard library and prelude.
|
/// standard library and prelude.
|
||||||
pub fn phase_2_configure_and_expand(sess: &Session,
|
pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
loader: &mut CrateLoader,
|
|
||||||
mut krate: ast::Crate,
|
mut krate: ast::Crate,
|
||||||
crate_id: &CrateId)
|
crate_id: &CrateId)
|
||||||
-> (ast::Crate, syntax::ast_map::Map) {
|
-> (ast::Crate, syntax::ast_map::Map) {
|
||||||
|
@ -197,25 +196,42 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
krate = time(time_passes, "configuration 1", krate, |krate|
|
krate = time(time_passes, "configuration 1", krate, |krate|
|
||||||
front::config::strip_unconfigured_items(krate));
|
front::config::strip_unconfigured_items(krate));
|
||||||
|
|
||||||
krate = time(time_passes, "expansion", krate, |krate| {
|
let Plugins { macros, registrars }
|
||||||
// Windows dlls do not have rpaths, so they don't know how to find their
|
= time(time_passes, "plugin loading", (), |_|
|
||||||
// dependencies. It's up to us to tell the system where to find all the
|
plugin::load::load_plugins(sess, &krate));
|
||||||
// dependent dlls. Note that this uses cfg!(windows) as opposed to
|
|
||||||
// targ_cfg because syntax extensions are always loaded for the host
|
let mut registry = Registry::new(&krate);
|
||||||
// compiler, not for the target.
|
|
||||||
if cfg!(windows) {
|
time(time_passes, "plugin registration", (), |_| {
|
||||||
sess.host_filesearch().add_dylib_search_paths();
|
for ®istrar in registrars.iter() {
|
||||||
|
registrar(&mut registry);
|
||||||
}
|
}
|
||||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
|
||||||
loader: loader,
|
|
||||||
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
|
||||||
crate_id: crate_id.clone(),
|
|
||||||
};
|
|
||||||
syntax::ext::expand::expand_crate(&sess.parse_sess,
|
|
||||||
cfg,
|
|
||||||
krate)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let Registry { syntax_exts, .. } = registry;
|
||||||
|
|
||||||
|
krate = time(time_passes, "expansion", (krate, macros, syntax_exts),
|
||||||
|
|(krate, macros, syntax_exts)| {
|
||||||
|
// Windows dlls do not have rpaths, so they don't know how to find their
|
||||||
|
// dependencies. It's up to us to tell the system where to find all the
|
||||||
|
// dependent dlls. Note that this uses cfg!(windows) as opposed to
|
||||||
|
// targ_cfg because syntax extensions are always loaded for the host
|
||||||
|
// compiler, not for the target.
|
||||||
|
if cfg!(windows) {
|
||||||
|
sess.host_filesearch().add_dylib_search_paths();
|
||||||
|
}
|
||||||
|
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||||
|
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
||||||
|
crate_id: crate_id.clone(),
|
||||||
|
};
|
||||||
|
syntax::ext::expand::expand_crate(&sess.parse_sess,
|
||||||
|
cfg,
|
||||||
|
macros,
|
||||||
|
syntax_exts,
|
||||||
|
krate)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// strip again, in case expansion added anything with a #[cfg].
|
// strip again, in case expansion added anything with a #[cfg].
|
||||||
krate = time(time_passes, "configuration 2", krate, |krate|
|
krate = time(time_passes, "configuration 2", krate, |krate|
|
||||||
front::config::strip_unconfigured_items(krate));
|
front::config::strip_unconfigured_items(krate));
|
||||||
|
@ -281,9 +297,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||||
time(time_passes, "looking for entry point", (),
|
time(time_passes, "looking for entry point", (),
|
||||||
|_| middle::entry::find_entry_point(&sess, krate, &ast_map));
|
|_| middle::entry::find_entry_point(&sess, krate, &ast_map));
|
||||||
|
|
||||||
sess.macro_registrar_fn.set(
|
sess.plugin_registrar_fn.set(
|
||||||
time(time_passes, "looking for macro registrar", (), |_|
|
time(time_passes, "looking for plugin registrar", (), |_|
|
||||||
syntax::ext::registrar::find_macro_registrar(
|
plugin::build::find_plugin_registrar(
|
||||||
sess.diagnostic(), krate)));
|
sess.diagnostic(), krate)));
|
||||||
|
|
||||||
let freevars = time(time_passes, "freevar finding", (), |_|
|
let freevars = time(time_passes, "freevar finding", (), |_|
|
||||||
|
@ -596,9 +612,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
|
|
||||||
let (krate, ast_map, is_expanded) = match ppm {
|
let (krate, ast_map, is_expanded) = match ppm {
|
||||||
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
||||||
let loader = &mut Loader::new(&sess);
|
|
||||||
let (krate, ast_map) = phase_2_configure_and_expand(&sess,
|
let (krate, ast_map) = phase_2_configure_and_expand(&sess,
|
||||||
loader,
|
|
||||||
krate,
|
krate,
|
||||||
&id);
|
&id);
|
||||||
(krate, Some(ast_map), true)
|
(krate, Some(ast_map), true)
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub struct Session {
|
||||||
// For a library crate, this is always none
|
// For a library crate, this is always none
|
||||||
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
|
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
|
||||||
pub entry_type: Cell<Option<config::EntryFnType>>,
|
pub entry_type: Cell<Option<config::EntryFnType>>,
|
||||||
pub macro_registrar_fn: Cell<Option<ast::NodeId>>,
|
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
|
||||||
pub default_sysroot: Option<Path>,
|
pub default_sysroot: Option<Path>,
|
||||||
// The name of the root source file of the crate, in the local file system. The path is always
|
// The name of the root source file of the crate, in the local file system. The path is always
|
||||||
// expected to be absolute. `None` means that there is no source file.
|
// expected to be absolute. `None` means that there is no source file.
|
||||||
|
@ -232,7 +232,7 @@ pub fn build_session_(sopts: config::Options,
|
||||||
// For a library crate, this is always none
|
// For a library crate, this is always none
|
||||||
entry_fn: RefCell::new(None),
|
entry_fn: RefCell::new(None),
|
||||||
entry_type: Cell::new(None),
|
entry_type: Cell::new(None),
|
||||||
macro_registrar_fn: Cell::new(None),
|
plugin_registrar_fn: Cell::new(None),
|
||||||
default_sysroot: default_sysroot,
|
default_sysroot: default_sysroot,
|
||||||
local_crate_source_file: local_crate_source_file,
|
local_crate_source_file: local_crate_source_file,
|
||||||
working_dir: os::getcwd(),
|
working_dir: os::getcwd(),
|
||||||
|
|
|
@ -46,7 +46,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
|
||||||
("thread_local", Active),
|
("thread_local", Active),
|
||||||
("link_args", Active),
|
("link_args", Active),
|
||||||
("phase", Active),
|
("phase", Active),
|
||||||
("macro_registrar", Active),
|
("plugin_registrar", Active),
|
||||||
("log_syntax", Active),
|
("log_syntax", Active),
|
||||||
("trace_macros", Active),
|
("trace_macros", Active),
|
||||||
("concat_idents", Active),
|
("concat_idents", Active),
|
||||||
|
@ -192,10 +192,9 @@ impl<'a> Visitor<()> for Context<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemFn(..) => {
|
ast::ItemFn(..) => {
|
||||||
if attr::contains_name(i.attrs.as_slice(), "macro_registrar") {
|
if attr::contains_name(i.attrs.as_slice(), "plugin_registrar") {
|
||||||
self.gate_feature("macro_registrar", i.span,
|
self.gate_feature("plugin_registrar", i.span,
|
||||||
"cross-crate macro exports are \
|
"compiler plugins are experimental and possibly buggy");
|
||||||
experimental and possibly buggy");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||||
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
|
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
|
||||||
InternedString::new("phase"),
|
InternedString::new("phase"),
|
||||||
vec!(
|
vec!(
|
||||||
attr::mk_word_item(InternedString::new("syntax")),
|
attr::mk_word_item(InternedString::new("plugin")),
|
||||||
attr::mk_word_item(InternedString::new("link")
|
attr::mk_word_item(InternedString::new("link")
|
||||||
))))),
|
))))),
|
||||||
vis: ast::Inherited,
|
vis: ast::Inherited,
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use front::config;
|
use front::config;
|
||||||
use front::std_inject::with_version;
|
use front::std_inject::with_version;
|
||||||
use metadata::creader::Loader;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -150,12 +149,10 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||||
|
|
||||||
fn generate_test_harness(sess: &Session, krate: ast::Crate)
|
fn generate_test_harness(sess: &Session, krate: ast::Crate)
|
||||||
-> ast::Crate {
|
-> ast::Crate {
|
||||||
let loader = &mut Loader::new(sess);
|
|
||||||
let mut cx: TestCtxt = TestCtxt {
|
let mut cx: TestCtxt = TestCtxt {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
|
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
|
||||||
ExpansionConfig {
|
ExpansionConfig {
|
||||||
loader: loader,
|
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_id: from_str("test").unwrap(),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -42,9 +42,14 @@ extern crate sync;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
pub mod middle {
|
pub mod middle {
|
||||||
pub mod def;
|
pub mod def;
|
||||||
pub mod trans;
|
pub mod trans;
|
||||||
|
@ -109,6 +114,8 @@ pub mod metadata;
|
||||||
|
|
||||||
pub mod driver;
|
pub mod driver;
|
||||||
|
|
||||||
|
pub mod plugin;
|
||||||
|
|
||||||
pub mod util {
|
pub mod util {
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod ppaux;
|
pub mod ppaux;
|
||||||
|
|
|
@ -198,7 +198,7 @@ pub static tag_native_libraries_lib: uint = 0x88;
|
||||||
pub static tag_native_libraries_name: uint = 0x89;
|
pub static tag_native_libraries_name: uint = 0x89;
|
||||||
pub static tag_native_libraries_kind: uint = 0x8a;
|
pub static tag_native_libraries_kind: uint = 0x8a;
|
||||||
|
|
||||||
pub static tag_macro_registrar_fn: uint = 0x8b;
|
pub static tag_plugin_registrar_fn: uint = 0x8b;
|
||||||
pub static tag_exported_macros: uint = 0x8c;
|
pub static tag_exported_macros: uint = 0x8c;
|
||||||
pub static tag_macro_def: uint = 0x8d;
|
pub static tag_macro_def: uint = 0x8d;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ use metadata::cstore::{CStore, CrateSource};
|
||||||
use metadata::decoder;
|
use metadata::decoder;
|
||||||
use metadata::loader;
|
use metadata::loader;
|
||||||
use metadata::loader::CratePaths;
|
use metadata::loader::CratePaths;
|
||||||
|
use plugin::load::PluginMetadata;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -30,7 +31,6 @@ use syntax::attr;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::codemap::{Span};
|
use syntax::codemap::{Span};
|
||||||
use syntax::diagnostic::SpanHandler;
|
use syntax::diagnostic::SpanHandler;
|
||||||
use syntax::ext::base::{CrateLoader, MacroCrate};
|
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::crateid::CrateId;
|
use syntax::crateid::CrateId;
|
||||||
|
@ -379,23 +379,21 @@ fn resolve_crate_deps(e: &mut Env,
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Loader<'a> {
|
pub struct PluginMetadataReader<'a> {
|
||||||
env: Env<'a>,
|
env: Env<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Loader<'a> {
|
impl<'a> PluginMetadataReader<'a> {
|
||||||
pub fn new(sess: &'a Session) -> Loader<'a> {
|
pub fn new(sess: &'a Session) -> PluginMetadataReader<'a> {
|
||||||
Loader {
|
PluginMetadataReader {
|
||||||
env: Env {
|
env: Env {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
next_crate_num: sess.cstore.next_crate_num(),
|
next_crate_num: sess.cstore.next_crate_num(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> CrateLoader for Loader<'a> {
|
pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata {
|
||||||
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
|
|
||||||
let info = extract_crate_info(&self.env, krate).unwrap();
|
let info = extract_crate_info(&self.env, krate).unwrap();
|
||||||
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
||||||
let is_cross = target_triple != driver::host_triple();
|
let is_cross = target_triple != driver::host_triple();
|
||||||
|
@ -425,8 +423,8 @@ impl<'a> CrateLoader for Loader<'a> {
|
||||||
load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os);
|
load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os);
|
||||||
load_ctxt.filesearch = self.env.sess.target_filesearch();
|
load_ctxt.filesearch = self.env.sess.target_filesearch();
|
||||||
let lib = load_ctxt.load_library_crate();
|
let lib = load_ctxt.load_library_crate();
|
||||||
if decoder::get_macro_registrar_fn(lib.metadata.as_slice()).is_some() {
|
if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
|
||||||
let message = format!("crate `{}` contains a macro_registrar fn but \
|
let message = format!("crate `{}` contains a plugin_registrar fn but \
|
||||||
only a version for triple `{}` could be found (need {})",
|
only a version for triple `{}` could be found (need {})",
|
||||||
info.ident, target_triple, driver::host_triple());
|
info.ident, target_triple, driver::host_triple());
|
||||||
self.env.sess.span_err(krate.span, message.as_slice());
|
self.env.sess.span_err(krate.span, message.as_slice());
|
||||||
|
@ -441,10 +439,10 @@ impl<'a> CrateLoader for Loader<'a> {
|
||||||
None => { load_ctxt.report_load_errs(); unreachable!() },
|
None => { load_ctxt.report_load_errs(); unreachable!() },
|
||||||
};
|
};
|
||||||
let macros = decoder::get_exported_macros(library.metadata.as_slice());
|
let macros = decoder::get_exported_macros(library.metadata.as_slice());
|
||||||
let registrar = decoder::get_macro_registrar_fn(library.metadata.as_slice()).map(|id| {
|
let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| {
|
||||||
decoder::get_symbol(library.metadata.as_slice(), id).to_string()
|
decoder::get_symbol(library.metadata.as_slice(), id).to_string()
|
||||||
});
|
});
|
||||||
let mc = MacroCrate {
|
let pc = PluginMetadata {
|
||||||
lib: library.dylib.clone(),
|
lib: library.dylib.clone(),
|
||||||
macros: macros.move_iter().map(|x| x.to_string()).collect(),
|
macros: macros.move_iter().map(|x| x.to_string()).collect(),
|
||||||
registrar_symbol: registrar,
|
registrar_symbol: registrar,
|
||||||
|
@ -454,6 +452,6 @@ impl<'a> CrateLoader for Loader<'a> {
|
||||||
register_crate(&mut self.env, &None, info.ident.as_slice(),
|
register_crate(&mut self.env, &None, info.ident.as_slice(),
|
||||||
&info.crate_id, krate.span, library);
|
&info.crate_id, krate.span, library);
|
||||||
}
|
}
|
||||||
mc
|
pc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,9 +139,6 @@ impl CStore {
|
||||||
.map(|source| source.clone())
|
.map(|source| source.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_phase_syntax_crates(&self) {
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(&self) {
|
pub fn reset(&self) {
|
||||||
self.metas.borrow_mut().clear();
|
self.metas.borrow_mut().clear();
|
||||||
self.extern_mod_crate_map.borrow_mut().clear();
|
self.extern_mod_crate_map.borrow_mut().clear();
|
||||||
|
|
|
@ -1255,8 +1255,8 @@ pub fn get_native_libraries(cdata: Cmd)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_macro_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
|
pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
|
||||||
reader::maybe_get_doc(ebml::Doc::new(data), tag_macro_registrar_fn)
|
reader::maybe_get_doc(ebml::Doc::new(data), tag_plugin_registrar_fn)
|
||||||
.map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
|
.map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1582,9 +1582,9 @@ fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
||||||
match ecx.tcx.sess.macro_registrar_fn.get() {
|
match ecx.tcx.sess.plugin_registrar_fn.get() {
|
||||||
Some(id) => { ebml_w.wr_tagged_u32(tag_macro_registrar_fn, id); }
|
Some(id) => { ebml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); }
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1791,7 +1791,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
dep_bytes: u64,
|
dep_bytes: u64,
|
||||||
lang_item_bytes: u64,
|
lang_item_bytes: u64,
|
||||||
native_lib_bytes: u64,
|
native_lib_bytes: u64,
|
||||||
macro_registrar_fn_bytes: u64,
|
plugin_registrar_fn_bytes: u64,
|
||||||
macro_defs_bytes: u64,
|
macro_defs_bytes: u64,
|
||||||
impl_bytes: u64,
|
impl_bytes: u64,
|
||||||
misc_bytes: u64,
|
misc_bytes: u64,
|
||||||
|
@ -1805,7 +1805,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
dep_bytes: 0,
|
dep_bytes: 0,
|
||||||
lang_item_bytes: 0,
|
lang_item_bytes: 0,
|
||||||
native_lib_bytes: 0,
|
native_lib_bytes: 0,
|
||||||
macro_registrar_fn_bytes: 0,
|
plugin_registrar_fn_bytes: 0,
|
||||||
macro_defs_bytes: 0,
|
macro_defs_bytes: 0,
|
||||||
impl_bytes: 0,
|
impl_bytes: 0,
|
||||||
misc_bytes: 0,
|
misc_bytes: 0,
|
||||||
|
@ -1870,10 +1870,10 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
encode_native_libraries(&ecx, &mut ebml_w);
|
encode_native_libraries(&ecx, &mut ebml_w);
|
||||||
stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i;
|
stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i;
|
||||||
|
|
||||||
// Encode the macro registrar function
|
// Encode the plugin registrar function
|
||||||
i = ebml_w.writer.tell().unwrap();
|
i = ebml_w.writer.tell().unwrap();
|
||||||
encode_macro_registrar_fn(&ecx, &mut ebml_w);
|
encode_plugin_registrar_fn(&ecx, &mut ebml_w);
|
||||||
stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
|
stats.plugin_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
|
||||||
|
|
||||||
// Encode macro definitions
|
// Encode macro definitions
|
||||||
i = ebml_w.writer.tell().unwrap();
|
i = ebml_w.writer.tell().unwrap();
|
||||||
|
@ -1912,18 +1912,18 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("metadata stats:");
|
println!("metadata stats:");
|
||||||
println!(" attribute bytes: {}", stats.attr_bytes);
|
println!(" attribute bytes: {}", stats.attr_bytes);
|
||||||
println!(" dep bytes: {}", stats.dep_bytes);
|
println!(" dep bytes: {}", stats.dep_bytes);
|
||||||
println!(" lang item bytes: {}", stats.lang_item_bytes);
|
println!(" lang item bytes: {}", stats.lang_item_bytes);
|
||||||
println!(" native bytes: {}", stats.native_lib_bytes);
|
println!(" native bytes: {}", stats.native_lib_bytes);
|
||||||
println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes);
|
println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
|
||||||
println!(" macro def bytes: {}", stats.macro_defs_bytes);
|
println!(" macro def bytes: {}", stats.macro_defs_bytes);
|
||||||
println!(" impl bytes: {}", stats.impl_bytes);
|
println!(" impl bytes: {}", stats.impl_bytes);
|
||||||
println!(" misc bytes: {}", stats.misc_bytes);
|
println!(" misc bytes: {}", stats.misc_bytes);
|
||||||
println!(" item bytes: {}", stats.item_bytes);
|
println!(" item bytes: {}", stats.item_bytes);
|
||||||
println!(" index bytes: {}", stats.index_bytes);
|
println!(" index bytes: {}", stats.index_bytes);
|
||||||
println!(" zero bytes: {}", stats.zero_bytes);
|
println!(" zero bytes: {}", stats.zero_bytes);
|
||||||
println!(" total bytes: {}", stats.total_bytes);
|
println!(" total bytes: {}", stats.total_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,25 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use ast;
|
//! Used by `rustc` when compiling a plugin crate.
|
||||||
use attr;
|
|
||||||
use codemap::Span;
|
|
||||||
use diagnostic;
|
|
||||||
use visit;
|
|
||||||
use visit::Visitor;
|
|
||||||
|
|
||||||
struct MacroRegistrarContext {
|
use syntax::ast;
|
||||||
|
use syntax::attr;
|
||||||
|
use syntax::codemap::Span;
|
||||||
|
use syntax::diagnostic;
|
||||||
|
use syntax::visit;
|
||||||
|
use syntax::visit::Visitor;
|
||||||
|
|
||||||
|
struct RegistrarFinder {
|
||||||
registrars: Vec<(ast::NodeId, Span)> ,
|
registrars: Vec<(ast::NodeId, Span)> ,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor<()> for MacroRegistrarContext {
|
impl Visitor<()> for RegistrarFinder {
|
||||||
fn visit_item(&mut self, item: &ast::Item, _: ()) {
|
fn visit_item(&mut self, item: &ast::Item, _: ()) {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemFn(..) => {
|
ast::ItemFn(..) => {
|
||||||
if attr::contains_name(item.attrs.as_slice(),
|
if attr::contains_name(item.attrs.as_slice(),
|
||||||
"macro_registrar") {
|
"plugin_registrar") {
|
||||||
self.registrars.push((item.id, item.span));
|
self.registrars.push((item.id, item.span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,20 +37,21 @@ impl Visitor<()> for MacroRegistrarContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_macro_registrar(diagnostic: &diagnostic::SpanHandler,
|
/// Find the function marked with `#[plugin_registrar]`, if any.
|
||||||
krate: &ast::Crate) -> Option<ast::NodeId> {
|
pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
|
||||||
let mut ctx = MacroRegistrarContext { registrars: Vec::new() };
|
krate: &ast::Crate) -> Option<ast::NodeId> {
|
||||||
visit::walk_crate(&mut ctx, krate, ());
|
let mut finder = RegistrarFinder { registrars: Vec::new() };
|
||||||
|
visit::walk_crate(&mut finder, krate, ());
|
||||||
|
|
||||||
match ctx.registrars.len() {
|
match finder.registrars.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => {
|
1 => {
|
||||||
let (node_id, _) = ctx.registrars.pop().unwrap();
|
let (node_id, _) = finder.registrars.pop().unwrap();
|
||||||
Some(node_id)
|
Some(node_id)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
diagnostic.handler().err("multiple macro registration functions found");
|
diagnostic.handler().err("multiple plugin registration functions found");
|
||||||
for &(_, span) in ctx.registrars.iter() {
|
for &(_, span) in finder.registrars.iter() {
|
||||||
diagnostic.span_note(span, "one is here");
|
diagnostic.span_note(span, "one is here");
|
||||||
}
|
}
|
||||||
diagnostic.handler().abort_if_errors();
|
diagnostic.handler().abort_if_errors();
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Copyright 2012-2013 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.
|
||||||
|
|
||||||
|
//! Used by `rustc` when loading a plugin.
|
||||||
|
|
||||||
|
use driver::session::Session;
|
||||||
|
use metadata::creader::PluginMetadataReader;
|
||||||
|
use plugin::registry::Registry;
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
use std::os;
|
||||||
|
use std::unstable::dynamic_lib::DynamicLibrary;
|
||||||
|
use syntax::ast;
|
||||||
|
use syntax::attr;
|
||||||
|
use syntax::visit;
|
||||||
|
use syntax::visit::Visitor;
|
||||||
|
use syntax::ext::expand::ExportedMacros;
|
||||||
|
use syntax::attr::AttrMetaMethods;
|
||||||
|
|
||||||
|
/// Plugin-related crate metadata.
|
||||||
|
pub struct PluginMetadata {
|
||||||
|
/// Source code of macros exported by the crate.
|
||||||
|
pub macros: Vec<String>,
|
||||||
|
/// Path to the shared library file.
|
||||||
|
pub lib: Option<Path>,
|
||||||
|
/// Symbol name of the plugin registrar function.
|
||||||
|
pub registrar_symbol: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pointer to a registrar function.
|
||||||
|
pub type PluginRegistrarFun =
|
||||||
|
fn(&mut Registry);
|
||||||
|
|
||||||
|
/// Information about loaded plugins.
|
||||||
|
pub struct Plugins {
|
||||||
|
/// Source code of exported macros.
|
||||||
|
pub macros: Vec<ExportedMacros>,
|
||||||
|
/// Registrars, as function pointers.
|
||||||
|
pub registrars: Vec<PluginRegistrarFun>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PluginLoader<'a> {
|
||||||
|
sess: &'a Session,
|
||||||
|
reader: PluginMetadataReader<'a>,
|
||||||
|
plugins: Plugins,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PluginLoader<'a> {
|
||||||
|
fn new(sess: &'a Session) -> PluginLoader<'a> {
|
||||||
|
PluginLoader {
|
||||||
|
sess: sess,
|
||||||
|
reader: PluginMetadataReader::new(sess),
|
||||||
|
plugins: Plugins {
|
||||||
|
macros: vec!(),
|
||||||
|
registrars: vec!(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read plugin metadata and dynamically load registrar functions.
|
||||||
|
pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins {
|
||||||
|
let mut loader = PluginLoader::new(sess);
|
||||||
|
visit::walk_crate(&mut loader, krate, ());
|
||||||
|
loader.plugins
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Visitor<()> for PluginLoader<'a> {
|
||||||
|
fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
|
||||||
|
match vi.node {
|
||||||
|
ast::ViewItemExternCrate(name, _, _) => {
|
||||||
|
let mut plugin_phase = false;
|
||||||
|
|
||||||
|
for attr in vi.attrs.iter().filter(|a| a.check_name("phase")) {
|
||||||
|
let phases = attr.meta_item_list().unwrap_or(&[]);
|
||||||
|
if attr::contains_name(phases, "plugin") {
|
||||||
|
plugin_phase = true;
|
||||||
|
}
|
||||||
|
if attr::contains_name(phases, "syntax") {
|
||||||
|
plugin_phase = true;
|
||||||
|
self.sess.span_warn(attr.span,
|
||||||
|
"phase(syntax) is a deprecated synonym for phase(plugin)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plugin_phase { return; }
|
||||||
|
|
||||||
|
let PluginMetadata { macros, lib, registrar_symbol } =
|
||||||
|
self.reader.read_plugin_metadata(vi);
|
||||||
|
|
||||||
|
self.plugins.macros.push(ExportedMacros {
|
||||||
|
crate_name: name,
|
||||||
|
macros: macros,
|
||||||
|
});
|
||||||
|
|
||||||
|
match (lib, registrar_symbol) {
|
||||||
|
(Some(lib), Some(symbol))
|
||||||
|
=> self.dylink_registrar(vi, lib, symbol),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PluginLoader<'a> {
|
||||||
|
// Dynamically link a registrar function into the compiler process.
|
||||||
|
fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
|
||||||
|
// Make sure the path contains a / or the linker will search for it.
|
||||||
|
let path = os::make_absolute(&path);
|
||||||
|
|
||||||
|
let lib = match DynamicLibrary::open(Some(&path)) {
|
||||||
|
Ok(lib) => lib,
|
||||||
|
// this is fatal: there are almost certainly macros we need
|
||||||
|
// inside this crate, so continue would spew "macro undefined"
|
||||||
|
// errors
|
||||||
|
Err(err) => self.sess.span_fatal(vi.span, err.as_slice())
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let registrar: PluginRegistrarFun =
|
||||||
|
match lib.symbol(symbol.as_slice()) {
|
||||||
|
Ok(registrar) => registrar,
|
||||||
|
// again fatal if we can't register macros
|
||||||
|
Err(err) => self.sess.span_fatal(vi.span, err.as_slice())
|
||||||
|
};
|
||||||
|
|
||||||
|
self.plugins.registrars.push(registrar);
|
||||||
|
|
||||||
|
// Intentionally leak the dynamic library. We can't ever unload it
|
||||||
|
// since the library can make things that will live arbitrarily long
|
||||||
|
// (e.g. an @-box cycle or a task).
|
||||||
|
mem::forget(lib);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2012-2013 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.
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Infrastructure for compiler plugins.
|
||||||
|
*
|
||||||
|
* Plugins are Rust libraries which extend the behavior of `rustc`
|
||||||
|
* in various ways.
|
||||||
|
*
|
||||||
|
* Plugin authors will use the `Registry` type re-exported by
|
||||||
|
* this module, along with its methods. The rest of the module
|
||||||
|
* is for use by `rustc` itself.
|
||||||
|
*
|
||||||
|
* To define a plugin, build a dylib crate with a
|
||||||
|
* `#[plugin_registrar]` function:
|
||||||
|
*
|
||||||
|
* ```rust,ignore
|
||||||
|
* #![crate_id = "myplugin"]
|
||||||
|
* #![crate_type = "dylib"]
|
||||||
|
* #![feature(plugin_registrar)]
|
||||||
|
*
|
||||||
|
* extern crate rustc;
|
||||||
|
*
|
||||||
|
* use rustc::plugin::Registry;
|
||||||
|
*
|
||||||
|
* #[plugin_registrar]
|
||||||
|
* pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
|
* reg.register_macro("mymacro", expand_mymacro);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* fn expand_mymacro(...) { // details elided
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* WARNING: We currently don't check that the registrar function
|
||||||
|
* has the appropriate type!
|
||||||
|
*
|
||||||
|
* To use a plugin while compiling another crate:
|
||||||
|
*
|
||||||
|
* ```rust
|
||||||
|
* #![feature(phase)]
|
||||||
|
*
|
||||||
|
* #[phase(plugin)]
|
||||||
|
* extern crate myplugin;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* If you also need the plugin crate available at runtime, use
|
||||||
|
* `phase(plugin, link)`.
|
||||||
|
*
|
||||||
|
* See `src/test/auxiliary/macro_crate_test.rs` and `src/libfourcc`
|
||||||
|
* for examples of syntax extension plugins.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub use self::registry::Registry;
|
||||||
|
|
||||||
|
pub mod registry;
|
||||||
|
pub mod load;
|
||||||
|
pub mod build;
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2012-2013 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.
|
||||||
|
|
||||||
|
//! Used by plugin crates to tell `rustc` about the plugins they provide.
|
||||||
|
|
||||||
|
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
||||||
|
use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander};
|
||||||
|
use syntax::ext::base::{MacroExpanderFn};
|
||||||
|
use syntax::codemap::Span;
|
||||||
|
use syntax::parse::token;
|
||||||
|
use syntax::ast;
|
||||||
|
|
||||||
|
/// Structure used to register plugins.
|
||||||
|
///
|
||||||
|
/// A plugin registrar function takes an `&mut Registry` and should call
|
||||||
|
/// methods to register its plugins.
|
||||||
|
///
|
||||||
|
/// This struct has public fields and other methods for use by `rustc`
|
||||||
|
/// itself. They are not documented here, and plugin authors should
|
||||||
|
/// not use them.
|
||||||
|
pub struct Registry {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub krate_span: Span,
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub syntax_exts: Vec<NamedSyntaxExtension>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Registry {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn new(krate: &ast::Crate) -> Registry {
|
||||||
|
Registry {
|
||||||
|
krate_span: krate.span,
|
||||||
|
syntax_exts: vec!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register a syntax extension of any kind.
|
||||||
|
///
|
||||||
|
/// This is the most general hook into `libsyntax`'s expansion behavior.
|
||||||
|
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
|
||||||
|
self.syntax_exts.push((name, match extension {
|
||||||
|
NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)),
|
||||||
|
IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
|
||||||
|
ItemDecorator(ext) => ItemDecorator(ext),
|
||||||
|
ItemModifier(ext) => ItemModifier(ext),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register a macro of the usual kind.
|
||||||
|
///
|
||||||
|
/// This is a convenience wrapper for `register_syntax_extension`.
|
||||||
|
/// It builds for you a `NormalTT` with a `BasicMacroExpander`,
|
||||||
|
/// and also takes care of interning the macro's name.
|
||||||
|
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
|
||||||
|
self.register_syntax_extension(
|
||||||
|
token::intern(name),
|
||||||
|
NormalTT(box BasicMacroExpander {
|
||||||
|
expander: expander,
|
||||||
|
span: None,
|
||||||
|
}, None));
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
use rustc;
|
use rustc;
|
||||||
use rustc::{driver, middle};
|
use rustc::{driver, middle};
|
||||||
use rustc::metadata::creader::Loader;
|
|
||||||
use rustc::middle::privacy;
|
use rustc::middle::privacy;
|
||||||
use rustc::middle::lint;
|
use rustc::middle::lint;
|
||||||
|
|
||||||
|
@ -100,8 +99,8 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let krate = phase_1_parse_input(&sess, cfg, &input);
|
let krate = phase_1_parse_input(&sess, cfg, &input);
|
||||||
let (krate, ast_map) = phase_2_configure_and_expand(&sess, &mut Loader::new(&sess),
|
let (krate, ast_map) = phase_2_configure_and_expand(&sess, krate,
|
||||||
krate, &from_str("rustdoc").unwrap());
|
&from_str("rustdoc").unwrap());
|
||||||
let driver::driver::CrateAnalysis {
|
let driver::driver::CrateAnalysis {
|
||||||
exported_items, public_items, ty_cx, ..
|
exported_items, public_items, ty_cx, ..
|
||||||
} = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
} = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
extern crate debug;
|
extern crate debug;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[phase(syntax, link)]
|
|
||||||
extern crate log;
|
|
||||||
extern crate rustc;
|
extern crate rustc;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
@ -28,6 +26,14 @@ extern crate syntax;
|
||||||
extern crate testing = "test";
|
extern crate testing = "test";
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
#[phase(syntax, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{File, MemWriter};
|
use std::io::{File, MemWriter};
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
|
@ -23,7 +23,6 @@ use rustc::back::link;
|
||||||
use rustc::driver::config;
|
use rustc::driver::config;
|
||||||
use rustc::driver::driver;
|
use rustc::driver::driver;
|
||||||
use rustc::driver::session;
|
use rustc::driver::session;
|
||||||
use rustc::metadata::creader::Loader;
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::{CodeMap, dummy_spanned};
|
use syntax::codemap::{CodeMap, dummy_spanned};
|
||||||
use syntax::diagnostic;
|
use syntax::diagnostic;
|
||||||
|
@ -68,7 +67,7 @@ pub fn run(input: &str,
|
||||||
@dummy_spanned(ast::MetaWord(cfg_))
|
@dummy_spanned(ast::MetaWord(cfg_))
|
||||||
}));
|
}));
|
||||||
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
|
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
|
||||||
let (krate, _) = driver::phase_2_configure_and_expand(&sess, &mut Loader::new(&sess), krate,
|
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
|
||||||
&from_str("rustdoc-test").unwrap());
|
&from_str("rustdoc-test").unwrap());
|
||||||
|
|
||||||
let ctx = @core::DocContext {
|
let ctx = @core::DocContext {
|
||||||
|
|
|
@ -19,8 +19,14 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![experimental]
|
#![experimental]
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
|
@ -28,7 +34,9 @@ extern crate collections;
|
||||||
#[cfg(test)] extern crate realrustrt = "rustrt";
|
#[cfg(test)] extern crate realrustrt = "rustrt";
|
||||||
#[cfg(test)] extern crate test;
|
#[cfg(test)] extern crate test;
|
||||||
#[cfg(test)] extern crate native;
|
#[cfg(test)] extern crate native;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate std;
|
|
||||||
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
|
||||||
|
|
||||||
pub use self::util::{Stdio, Stdout, Stderr};
|
pub use self::util::{Stdio, Stdout, Stderr};
|
||||||
pub use self::unwind::{begin_unwind, begin_unwind_fmt};
|
pub use self::unwind::{begin_unwind, begin_unwind_fmt};
|
||||||
|
|
|
@ -27,9 +27,15 @@ Core encoding and decoding interfaces.
|
||||||
// test harness access
|
// test harness access
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
|
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
|
||||||
DecoderHelpers, EncoderHelpers};
|
DecoderHelpers, EncoderHelpers};
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,8 @@
|
||||||
#[cfg(test)] extern crate native;
|
#[cfg(test)] extern crate native;
|
||||||
#[cfg(test)] extern crate green;
|
#[cfg(test)] extern crate green;
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
|
@ -25,9 +25,12 @@
|
||||||
|
|
||||||
#![deny(missing_doc)]
|
#![deny(missing_doc)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test, stage0)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
|
#[cfg(test, not(stage0))]
|
||||||
|
#[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
pub use comm::{DuplexStream, duplex};
|
pub use comm::{DuplexStream, duplex};
|
||||||
|
|
|
@ -95,9 +95,6 @@ impl IdentMacroExpander for BasicIdentMacroExpander {
|
||||||
pub type IdentMacroExpanderFn =
|
pub type IdentMacroExpanderFn =
|
||||||
fn(&mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult>;
|
fn(&mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult>;
|
||||||
|
|
||||||
pub type MacroCrateRegistrationFun =
|
|
||||||
fn(|ast::Name, SyntaxExtension|);
|
|
||||||
|
|
||||||
/// The result of a macro expansion. The return values of the various
|
/// The result of a macro expansion. The return values of the various
|
||||||
/// methods are spliced into the AST at the callsite of the macro (or
|
/// methods are spliced into the AST at the callsite of the macro (or
|
||||||
/// just into the compiler's internal macro table, for `make_def`).
|
/// just into the compiler's internal macro table, for `make_def`).
|
||||||
|
@ -268,6 +265,8 @@ pub enum SyntaxExtension {
|
||||||
IdentTT(Box<IdentMacroExpander:'static>, Option<Span>),
|
IdentTT(Box<IdentMacroExpander:'static>, Option<Span>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type NamedSyntaxExtension = (Name, SyntaxExtension);
|
||||||
|
|
||||||
pub struct BlockInfo {
|
pub struct BlockInfo {
|
||||||
// should macros escape from this scope?
|
// should macros escape from this scope?
|
||||||
pub macros_escape: bool,
|
pub macros_escape: bool,
|
||||||
|
@ -392,16 +391,6 @@ pub fn syntax_expander_table() -> SyntaxEnv {
|
||||||
syntax_expanders
|
syntax_expanders
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MacroCrate {
|
|
||||||
pub lib: Option<Path>,
|
|
||||||
pub macros: Vec<String>,
|
|
||||||
pub registrar_symbol: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait CrateLoader {
|
|
||||||
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// One of these is made during expansion and incrementally updated as we go;
|
// One of these is made during expansion and incrementally updated as we go;
|
||||||
// when a macro expansion occurs, the resulting nodes have the backtrace()
|
// when a macro expansion occurs, the resulting nodes have the backtrace()
|
||||||
// -> expn_info of their expansion context stored into their span.
|
// -> expn_info of their expansion context stored into their span.
|
||||||
|
@ -409,7 +398,7 @@ pub struct ExtCtxt<'a> {
|
||||||
pub parse_sess: &'a parse::ParseSess,
|
pub parse_sess: &'a parse::ParseSess,
|
||||||
pub cfg: ast::CrateConfig,
|
pub cfg: ast::CrateConfig,
|
||||||
pub backtrace: Option<@ExpnInfo>,
|
pub backtrace: Option<@ExpnInfo>,
|
||||||
pub ecfg: expand::ExpansionConfig<'a>,
|
pub ecfg: expand::ExpansionConfig,
|
||||||
|
|
||||||
pub mod_path: Vec<ast::Ident> ,
|
pub mod_path: Vec<ast::Ident> ,
|
||||||
pub trace_mac: bool,
|
pub trace_mac: bool,
|
||||||
|
@ -417,7 +406,7 @@ pub struct ExtCtxt<'a> {
|
||||||
|
|
||||||
impl<'a> ExtCtxt<'a> {
|
impl<'a> ExtCtxt<'a> {
|
||||||
pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
|
pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
|
||||||
ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
|
ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
|
||||||
ExtCtxt {
|
ExtCtxt {
|
||||||
parse_sess: parse_sess,
|
parse_sess: parse_sess,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
|
|
@ -29,10 +29,6 @@ use visit;
|
||||||
use visit::Visitor;
|
use visit::Visitor;
|
||||||
use util::small_vector::SmallVector;
|
use util::small_vector::SmallVector;
|
||||||
|
|
||||||
use std::mem;
|
|
||||||
use std::os;
|
|
||||||
use std::unstable::dynamic_lib::DynamicLibrary;
|
|
||||||
|
|
||||||
pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
|
pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
|
||||||
match e.node {
|
match e.node {
|
||||||
// expr_mac should really be expr_ext or something; it's the
|
// expr_mac should really be expr_ext or something; it's the
|
||||||
|
@ -497,96 +493,6 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load macros from syntax-phase crates
|
|
||||||
pub fn expand_view_item(vi: &ast::ViewItem,
|
|
||||||
fld: &mut MacroExpander)
|
|
||||||
-> ast::ViewItem {
|
|
||||||
match vi.node {
|
|
||||||
ast::ViewItemExternCrate(..) => {
|
|
||||||
let should_load = vi.attrs.iter().any(|attr| {
|
|
||||||
attr.check_name("phase") &&
|
|
||||||
attr.meta_item_list().map_or(false, |phases| {
|
|
||||||
attr::contains_name(phases, "syntax")
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if should_load {
|
|
||||||
load_extern_macros(vi, fld);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::ViewItemUse(_) => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
noop_fold_view_item(vi, fld)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
|
|
||||||
let MacroCrate { lib, macros, registrar_symbol } =
|
|
||||||
fld.cx.ecfg.loader.load_crate(krate);
|
|
||||||
|
|
||||||
let crate_name = match krate.node {
|
|
||||||
ast::ViewItemExternCrate(name, _, _) => name,
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
let name = format!("<{} macros>", token::get_ident(crate_name));
|
|
||||||
let name = name.to_string();
|
|
||||||
|
|
||||||
for source in macros.iter() {
|
|
||||||
let item = parse::parse_item_from_source_str(name.clone(),
|
|
||||||
(*source).clone(),
|
|
||||||
fld.cx.cfg(),
|
|
||||||
fld.cx.parse_sess())
|
|
||||||
.expect("expected a serialized item");
|
|
||||||
expand_item_mac(item, fld);
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = match lib {
|
|
||||||
Some(path) => path,
|
|
||||||
None => return
|
|
||||||
};
|
|
||||||
// Make sure the path contains a / or the linker will search for it.
|
|
||||||
let path = os::make_absolute(&path);
|
|
||||||
|
|
||||||
let registrar = match registrar_symbol {
|
|
||||||
Some(registrar) => registrar,
|
|
||||||
None => return
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("load_extern_macros: mapped crate {} to path {} and registrar {:s}",
|
|
||||||
crate_name, path.display(), registrar);
|
|
||||||
|
|
||||||
let lib = match DynamicLibrary::open(Some(&path)) {
|
|
||||||
Ok(lib) => lib,
|
|
||||||
// this is fatal: there are almost certainly macros we need
|
|
||||||
// inside this crate, so continue would spew "macro undefined"
|
|
||||||
// errors
|
|
||||||
Err(err) => fld.cx.span_fatal(krate.span, err.as_slice())
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let registrar: MacroCrateRegistrationFun =
|
|
||||||
match lib.symbol(registrar.as_slice()) {
|
|
||||||
Ok(registrar) => registrar,
|
|
||||||
// again fatal if we can't register macros
|
|
||||||
Err(err) => fld.cx.span_fatal(krate.span, err.as_slice())
|
|
||||||
};
|
|
||||||
registrar(|name, extension| {
|
|
||||||
let extension = match extension {
|
|
||||||
NormalTT(ext, _) => NormalTT(ext, Some(krate.span)),
|
|
||||||
IdentTT(ext, _) => IdentTT(ext, Some(krate.span)),
|
|
||||||
ItemDecorator(ext) => ItemDecorator(ext),
|
|
||||||
ItemModifier(ext) => ItemModifier(ext),
|
|
||||||
};
|
|
||||||
fld.extsbox.insert(name, extension);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Intentionally leak the dynamic library. We can't ever unload it
|
|
||||||
// since the library can do things that will outlive the expansion
|
|
||||||
// phase (e.g. make an @-box cycle or launch a task).
|
|
||||||
mem::forget(lib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// expand a stmt
|
// expand a stmt
|
||||||
pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
|
pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
|
||||||
// why the copying here and not in expand_expr?
|
// why the copying here and not in expand_expr?
|
||||||
|
@ -969,10 +875,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||||
expand_item(item, self)
|
expand_item(item, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_view_item(&mut self, vi: &ast::ViewItem) -> ast::ViewItem {
|
|
||||||
expand_view_item(vi, self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> {
|
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> {
|
||||||
expand_stmt(stmt, self)
|
expand_stmt(stmt, self)
|
||||||
}
|
}
|
||||||
|
@ -986,14 +888,20 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExpansionConfig<'a> {
|
pub struct ExpansionConfig {
|
||||||
pub loader: &'a mut CrateLoader,
|
|
||||||
pub deriving_hash_type_parameter: bool,
|
pub deriving_hash_type_parameter: bool,
|
||||||
pub crate_id: CrateId,
|
pub crate_id: CrateId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ExportedMacros {
|
||||||
|
pub crate_name: Ident,
|
||||||
|
pub macros: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expand_crate(parse_sess: &parse::ParseSess,
|
pub fn expand_crate(parse_sess: &parse::ParseSess,
|
||||||
cfg: ExpansionConfig,
|
cfg: ExpansionConfig,
|
||||||
|
macros: Vec<ExportedMacros>,
|
||||||
|
user_exts: Vec<NamedSyntaxExtension>,
|
||||||
c: Crate) -> Crate {
|
c: Crate) -> Crate {
|
||||||
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
|
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
|
||||||
let mut expander = MacroExpander {
|
let mut expander = MacroExpander {
|
||||||
|
@ -1001,6 +909,24 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
|
||||||
cx: &mut cx,
|
cx: &mut cx,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for ExportedMacros { crate_name, macros } in macros.move_iter() {
|
||||||
|
let name = format!("<{} macros>", token::get_ident(crate_name))
|
||||||
|
.into_string();
|
||||||
|
|
||||||
|
for source in macros.move_iter() {
|
||||||
|
let item = parse::parse_item_from_source_str(name.clone(),
|
||||||
|
source,
|
||||||
|
expander.cx.cfg(),
|
||||||
|
expander.cx.parse_sess())
|
||||||
|
.expect("expected a serialized item");
|
||||||
|
expand_item_mac(item, &mut expander);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (name, extension) in user_exts.move_iter() {
|
||||||
|
expander.extsbox.insert(name, extension);
|
||||||
|
}
|
||||||
|
|
||||||
let ret = expander.fold_crate(c);
|
let ret = expander.fold_crate(c);
|
||||||
parse_sess.span_diagnostic.handler().abort_if_errors();
|
parse_sess.span_diagnostic.handler().abort_if_errors();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1093,7 +1019,6 @@ mod test {
|
||||||
use attr;
|
use attr;
|
||||||
use codemap;
|
use codemap;
|
||||||
use codemap::Spanned;
|
use codemap::Spanned;
|
||||||
use ext::base::{CrateLoader, MacroCrate};
|
|
||||||
use ext::mtwt;
|
use ext::mtwt;
|
||||||
use parse;
|
use parse;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
|
@ -1137,14 +1062,6 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ErrLoader;
|
|
||||||
|
|
||||||
impl CrateLoader for ErrLoader {
|
|
||||||
fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
|
|
||||||
fail!("lolwut")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// these following tests are quite fragile, in that they don't test what
|
// these following tests are quite fragile, in that they don't test what
|
||||||
// *kind* of failure occurs.
|
// *kind* of failure occurs.
|
||||||
|
|
||||||
|
@ -1159,13 +1076,11 @@ mod test {
|
||||||
src,
|
src,
|
||||||
Vec::new(), &sess);
|
Vec::new(), &sess);
|
||||||
// should fail:
|
// should fail:
|
||||||
let mut loader = ErrLoader;
|
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
loader: &mut loader,
|
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_id: from_str("test").unwrap(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess,cfg,crate_ast);
|
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that macros can leave scope for modules
|
// make sure that macros can leave scope for modules
|
||||||
|
@ -1178,14 +1093,11 @@ mod test {
|
||||||
"<test>".to_string(),
|
"<test>".to_string(),
|
||||||
src,
|
src,
|
||||||
Vec::new(), &sess);
|
Vec::new(), &sess);
|
||||||
// should fail:
|
|
||||||
let mut loader = ErrLoader;
|
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
loader: &mut loader,
|
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_id: from_str("test").unwrap(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess,cfg,crate_ast);
|
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// macro_escape modules shouldn't cause macros to leave scope
|
// macro_escape modules shouldn't cause macros to leave scope
|
||||||
|
@ -1198,13 +1110,11 @@ mod test {
|
||||||
src,
|
src,
|
||||||
Vec::new(), &sess);
|
Vec::new(), &sess);
|
||||||
// should fail:
|
// should fail:
|
||||||
let mut loader = ErrLoader;
|
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
loader: &mut loader,
|
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_id: from_str("test").unwrap(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess, cfg, crate_ast);
|
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn test_contains_flatten (){
|
#[test] fn test_contains_flatten (){
|
||||||
|
@ -1237,13 +1147,11 @@ mod test {
|
||||||
let ps = parse::new_parse_sess();
|
let ps = parse::new_parse_sess();
|
||||||
let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
|
let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
|
||||||
// the cfg argument actually does matter, here...
|
// the cfg argument actually does matter, here...
|
||||||
let mut loader = ErrLoader;
|
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
loader: &mut loader,
|
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_id: from_str("test").unwrap(),
|
||||||
};
|
};
|
||||||
expand_crate(&ps,cfg,crate_ast)
|
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
|
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
|
||||||
|
|
|
@ -32,8 +32,15 @@ This API is completely unstable and subject to change.
|
||||||
|
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate term;
|
extern crate term;
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[phase(syntax, link)]
|
#[phase(syntax, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[phase(plugin, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
extern crate fmt_macros;
|
extern crate fmt_macros;
|
||||||
extern crate debug;
|
extern crate debug;
|
||||||
|
|
||||||
|
@ -74,7 +81,6 @@ pub mod ext {
|
||||||
pub mod asm;
|
pub mod asm;
|
||||||
pub mod base;
|
pub mod base;
|
||||||
pub mod expand;
|
pub mod expand;
|
||||||
pub mod registrar;
|
|
||||||
|
|
||||||
pub mod quote;
|
pub mod quote;
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@
|
||||||
|
|
||||||
#![deny(missing_doc)]
|
#![deny(missing_doc)]
|
||||||
|
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[cfg(stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
pub use terminfo::TerminfoTerminal;
|
pub use terminfo::TerminfoTerminal;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
#![deny(deprecated_owned_vector)]
|
#![deny(deprecated_owned_vector)]
|
||||||
|
|
||||||
#[cfg(test)] extern crate debug;
|
#[cfg(test)] extern crate debug;
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
|
||||||
|
#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
|
||||||
|
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
|
@ -13,6 +13,6 @@
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)] extern crate t1 = "issue-13560-1";
|
#[phase(plugin)] extern crate t1 = "issue-13560-1";
|
||||||
#[phase(syntax, link)] extern crate t2 = "issue-13560-2";
|
#[phase(plugin, link)] extern crate t2 = "issue-13560-2";
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
extern crate debug;
|
extern crate debug;
|
||||||
|
|
||||||
pub fn foo<T>() {
|
pub fn foo<T>() {
|
||||||
|
|
|
@ -10,29 +10,28 @@
|
||||||
|
|
||||||
// force-host
|
// force-host
|
||||||
|
|
||||||
#![feature(globs, macro_registrar, macro_rules, quote, managed_boxes)]
|
#![feature(globs, plugin_registrar, macro_rules, quote, managed_boxes)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate rustc;
|
||||||
|
|
||||||
use syntax::ast::{Name, TokenTree, Item, MetaItem};
|
use syntax::ast::{TokenTree, Item, MetaItem};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! exported_macro (() => (2))
|
macro_rules! exported_macro (() => (2))
|
||||||
|
|
||||||
macro_rules! unexported_macro (() => (3))
|
macro_rules! unexported_macro (() => (3))
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
register(token::intern("make_a_1"),
|
reg.register_macro("make_a_1", expand_make_a_1);
|
||||||
NormalTT(box BasicMacroExpander {
|
reg.register_syntax_extension(
|
||||||
expander: expand_make_a_1,
|
token::intern("into_foo"),
|
||||||
span: None,
|
ItemModifier(expand_into_foo));
|
||||||
},
|
|
||||||
None));
|
|
||||||
register(token::intern("into_foo"), ItemModifier(expand_into_foo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
||||||
|
|
|
@ -10,13 +10,12 @@
|
||||||
|
|
||||||
// force-host
|
// force-host
|
||||||
|
|
||||||
#![feature(macro_registrar)]
|
#![feature(plugin_registrar)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate rustc;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use syntax::ast::Name;
|
use rustc::plugin::Registry;
|
||||||
use syntax::ext::base::SyntaxExtension;
|
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
foo: int
|
foo: int
|
||||||
|
@ -26,8 +25,8 @@ impl Drop for Foo {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn registrar(_: |Name, SyntaxExtension|) {
|
pub fn registrar(_: &mut Registry) {
|
||||||
local_data_key!(foo: Box<Any:Send>);
|
local_data_key!(foo: Box<Any:Send>);
|
||||||
foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>));
|
foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>));
|
||||||
}
|
}
|
|
@ -12,24 +12,20 @@
|
||||||
// no-prefer-dynamic
|
// no-prefer-dynamic
|
||||||
|
|
||||||
#![crate_type = "dylib"]
|
#![crate_type = "dylib"]
|
||||||
#![feature(macro_registrar, quote, globs)]
|
#![feature(plugin_registrar, quote, globs)]
|
||||||
|
|
||||||
extern crate other = "syntax-extension-with-dll-deps-1";
|
extern crate other = "syntax-extension-with-dll-deps-1";
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate rustc;
|
||||||
|
|
||||||
use syntax::ast::{Name, TokenTree, Item, MetaItem};
|
use syntax::ast::{TokenTree, Item, MetaItem};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::parse::token;
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
register(token::intern("foo"),
|
reg.register_macro("foo", expand_foo);
|
||||||
NormalTT(box BasicMacroExpander {
|
|
||||||
expander: expand_foo,
|
|
||||||
span: None,
|
|
||||||
},
|
|
||||||
None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
|
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
struct A;
|
struct A;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// no-pretty-expanded
|
// no-pretty-expanded
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax)] extern crate green;
|
#[phase(plugin)] extern crate green;
|
||||||
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax)] extern crate green;
|
#[phase(plugin)] extern crate green;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#![feature(macro_rules, phase)]
|
#![feature(macro_rules, phase)]
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(syntax)]extern crate regex_macros;
|
#[phase(plugin)]extern crate regex_macros;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#![allow(non_snake_case_functions)]
|
#![allow(non_snake_case_functions)]
|
||||||
#[phase(syntax)] extern crate green;
|
#[phase(plugin)] extern crate green;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax)] extern crate green;
|
#[phase(plugin)] extern crate green;
|
||||||
green_start!(main)
|
green_start!(main)
|
||||||
|
|
||||||
fn start(n_tasks: int, token: int) {
|
fn start(n_tasks: int, token: int) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// aux-build:macro_crate_test.rs
|
// aux-build:macro_crate_test.rs
|
||||||
// ignore-stage1
|
// ignore-stage1
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
//~^ ERROR compile time crate loading is experimental and possibly buggy
|
//~^ ERROR compile time crate loading is experimental and possibly buggy
|
||||||
extern crate macro_crate_test;
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_crate_test;
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate doesnt_exist; //~ ERROR can't find crate
|
extern crate doesnt_exist; //~ ERROR can't find crate
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_crate_test;
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate hexfloat;
|
extern crate hexfloat;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate hexfloat;
|
extern crate hexfloat;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(syntax)] extern crate regex_macros;
|
#[phase(plugin)] extern crate regex_macros;
|
||||||
|
|
||||||
// Tests to make sure that `regex!` will produce a compile error when given
|
// Tests to make sure that `regex!` will produce a compile error when given
|
||||||
// an invalid regular expression.
|
// an invalid regular expression.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(syntax)] extern crate regex_macros;
|
#[phase(plugin)] extern crate regex_macros;
|
||||||
|
|
||||||
#[deny(unused_variable)]
|
#[deny(unused_variable)]
|
||||||
#[deny(dead_code)]
|
#[deny(dead_code)]
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(syntax)] extern crate regex_macros;
|
#[phase(plugin)] extern crate regex_macros;
|
||||||
|
|
||||||
#[deny(unused_variable)]
|
#[deny(unused_variable)]
|
||||||
#[deny(dead_code)]
|
#[deny(dead_code)]
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// the registration function isn't typechecked yet
|
// the registration function isn't typechecked yet
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn registrar() {} //~ ERROR cross-crate macro exports are experimental
|
pub fn registrar() {} //~ ERROR compiler plugins are experimental
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
|
@ -8,15 +8,15 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: multiple macro registration functions found
|
// error-pattern: multiple plugin registration functions found
|
||||||
|
|
||||||
#![feature(macro_registrar)]
|
#![feature(plugin_registrar)]
|
||||||
|
|
||||||
// the registration function isn't typechecked yet
|
// the registration function isn't typechecked yet
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn one() {}
|
pub fn one() {}
|
||||||
|
|
||||||
#[macro_registrar]
|
#[plugin_registrar]
|
||||||
pub fn two() {}
|
pub fn two() {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
|
@ -11,7 +11,7 @@
|
||||||
// error-pattern:whatever
|
// error-pattern:whatever
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// error-pattern:whatever
|
// error-pattern:whatever
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// error-pattern:whatever
|
// error-pattern:whatever
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(plugin, link)] extern crate log;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
extern crate lib;
|
extern crate lib;
|
||||||
#[phase(syntax)] extern crate fourcc;
|
#[phase(plugin)] extern crate fourcc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fourcc!("1234");
|
fourcc!("1234");
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// aux-build:macro_crate_outlive_expansion_phase.rs
|
// aux-build:plugin_crate_outlive_expansion_phase.rs
|
||||||
// ignore-stage1
|
// ignore-stage1
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_crate_outlive_expansion_phase;
|
extern crate plugin_crate_outlive_expansion_phase;
|
||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_crate_test;
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
#[into_foo]
|
#[into_foo]
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate macro_crate_test;
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate fourcc;
|
extern crate fourcc;
|
||||||
|
|
||||||
static static_val: u32 = fourcc!("foo ");
|
static static_val: u32 = fourcc!("foo ");
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// ignore-pretty
|
// ignore-pretty
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate hexfloat;
|
extern crate hexfloat;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate extension = "syntax-extension-with-dll-deps-2";
|
extern crate extension = "syntax-extension-with-dll-deps-2";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate native;
|
extern crate native;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// exec-env:RUST_LOG=conditional-debug-macro-off=4
|
// exec-env:RUST_LOG=conditional-debug-macro-off=4
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate debug;
|
extern crate debug;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2013-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(phase)]
|
||||||
|
|
||||||
|
//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin)
|
||||||
|
#[phase(syntax, link)]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
debug!("foo");
|
||||||
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate green;
|
extern crate green;
|
||||||
extern crate native;
|
extern crate native;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// exec-env:RUST_LOG=logging-enabled-debug=debug
|
// exec-env:RUST_LOG=logging-enabled-debug=debug
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// exec-env:RUST_LOG=logging-enabled=info
|
// exec-env:RUST_LOG=logging-enabled=info
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use std::io::Command;
|
use std::io::Command;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_crate_def_only;
|
extern crate macro_crate_def_only;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
extern crate macro_export_inner_module;
|
extern crate macro_export_inner_module;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
|
|
||||||
#[phase(syntax)]
|
#[phase(plugin)]
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// exec-env:RUST_LOG=debug
|
// exec-env:RUST_LOG=debug
|
||||||
|
|
||||||
#![feature(phase)]
|
#![feature(phase)]
|
||||||
#[phase(syntax, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate green;
|
extern crate green;
|
||||||
|
|
Loading…
Reference in New Issue