mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-25 13:24:22 +00:00
std: Document builtin syntax extensions
These syntax extensions need a place to be documented, and this starts passing a `--cfg dox` parameter to `rustdoc` when building and testing documentation in order to document macros so that they have no effect on the compiled crate, but only documentation. Closes #5605
This commit is contained in:
parent
bb31cb8d2e
commit
78937b9779
@ -271,7 +271,7 @@ endif
|
|||||||
$(2) += doc/$(1)/index.html
|
$(2) += doc/$(1)/index.html
|
||||||
doc/$(1)/index.html: $$(LIB_DOC_DEP_$(1))
|
doc/$(1)/index.html: $$(LIB_DOC_DEP_$(1))
|
||||||
@$$(call E, rustdoc $$@)
|
@$$(call E, rustdoc $$@)
|
||||||
$$(Q)$$(RUSTDOC) --cfg stage2 $$<
|
$$(Q)$$(RUSTDOC) --cfg dox --cfg stage2 $$<
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(foreach crate,$(DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),DOC_TARGETS)))
|
$(foreach crate,$(DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),DOC_TARGETS)))
|
||||||
|
@ -694,7 +694,7 @@ endif
|
|||||||
ifeq ($(2),$$(CFG_BUILD))
|
ifeq ($(2),$$(CFG_BUILD))
|
||||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
|
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
|
||||||
@$$(call E, run doc-$(4) [$(2)])
|
@$$(call E, run doc-$(4) [$(2)])
|
||||||
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test $$< --test-args "$$(TESTARGS)" && touch $$@
|
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --cfg dox --test $$< --test-args "$$(TESTARGS)" && touch $$@
|
||||||
else
|
else
|
||||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
|
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
|
||||||
touch $$@
|
touch $$@
|
||||||
|
@ -168,6 +168,7 @@ pub fn main_args(args: &[~str]) -> int {
|
|||||||
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
|
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
|
||||||
|
|
||||||
let output = matches.opt_str("o").map(|s| Path::new(s));
|
let output = matches.opt_str("o").map(|s| Path::new(s));
|
||||||
|
let cfgs = matches.opt_strs("cfg");
|
||||||
|
|
||||||
match (should_test, markdown_input) {
|
match (should_test, markdown_input) {
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
@ -175,7 +176,8 @@ pub fn main_args(args: &[~str]) -> int {
|
|||||||
libs,
|
libs,
|
||||||
test_args.move_iter().collect())
|
test_args.move_iter().collect())
|
||||||
}
|
}
|
||||||
(true, false) => return test::run(input, libs, test_args),
|
(true, false) => return test::run(input, cfgs.move_iter().collect(),
|
||||||
|
libs, test_args),
|
||||||
|
|
||||||
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
|
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
|
||||||
&matches),
|
&matches),
|
||||||
|
@ -22,8 +22,10 @@ use rustc::back::link;
|
|||||||
use rustc::driver::driver;
|
use rustc::driver::driver;
|
||||||
use rustc::driver::session;
|
use rustc::driver::session;
|
||||||
use rustc::metadata::creader::Loader;
|
use rustc::metadata::creader::Loader;
|
||||||
|
use syntax::ast;
|
||||||
|
use syntax::codemap::{CodeMap, dummy_spanned};
|
||||||
use syntax::diagnostic;
|
use syntax::diagnostic;
|
||||||
use syntax::codemap::CodeMap;
|
use syntax::parse::token;
|
||||||
|
|
||||||
use core;
|
use core;
|
||||||
use clean;
|
use clean;
|
||||||
@ -33,7 +35,8 @@ use html::markdown;
|
|||||||
use passes;
|
use passes;
|
||||||
use visit_ast::RustdocVisitor;
|
use visit_ast::RustdocVisitor;
|
||||||
|
|
||||||
pub fn run(input: &str, libs: HashSet<Path>, mut test_args: Vec<~str>) -> int {
|
pub fn run(input: &str, cfgs: Vec<~str>,
|
||||||
|
libs: HashSet<Path>, mut test_args: Vec<~str>) -> int {
|
||||||
let input_path = Path::new(input);
|
let input_path = Path::new(input);
|
||||||
let input = driver::FileInput(input_path.clone());
|
let input = driver::FileInput(input_path.clone());
|
||||||
|
|
||||||
@ -54,7 +57,11 @@ pub fn run(input: &str, libs: HashSet<Path>, mut test_args: Vec<~str>) -> int {
|
|||||||
Some(input_path),
|
Some(input_path),
|
||||||
span_diagnostic_handler);
|
span_diagnostic_handler);
|
||||||
|
|
||||||
let cfg = driver::build_configuration(&sess);
|
let mut cfg = driver::build_configuration(&sess);
|
||||||
|
cfg.extend(cfgs.move_iter().map(|cfg_| {
|
||||||
|
let cfg_ = token::intern_and_get_ident(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, &mut Loader::new(&sess), krate,
|
||||||
&from_str("rustdoc-test").unwrap());
|
&from_str("rustdoc-test").unwrap());
|
||||||
@ -160,17 +167,14 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
|||||||
|
|
||||||
fn maketest(s: &str, cratename: &str, loose_feature_gating: bool) -> ~str {
|
fn maketest(s: &str, cratename: &str, loose_feature_gating: bool) -> ~str {
|
||||||
let mut prog = ~r"
|
let mut prog = ~r"
|
||||||
#[deny(warnings)];
|
#![deny(warnings)]
|
||||||
#[allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)];
|
#![allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)]
|
||||||
|
|
||||||
// FIXME: remove when ~[] disappears from tests.
|
|
||||||
#[allow(deprecated_owned_vector)];
|
|
||||||
";
|
";
|
||||||
|
|
||||||
if loose_feature_gating {
|
if loose_feature_gating {
|
||||||
// FIXME #12773: avoid inserting these when the tutorial & manual
|
// FIXME #12773: avoid inserting these when the tutorial & manual
|
||||||
// etc. have been updated to not use them so prolifically.
|
// etc. have been updated to not use them so prolifically.
|
||||||
prog.push_str("#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n");
|
prog.push_str("#![feature(macro_rules, globs, struct_variant, managed_boxes) ]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.contains("extern crate") {
|
if !s.contains("extern crate") {
|
||||||
|
@ -332,3 +332,262 @@ macro_rules! log (
|
|||||||
if log_enabled!($lvl) { println!($($args)*) }
|
if log_enabled!($lvl) { println!($($args)*) }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/// Built-in macros to the compiler itself.
|
||||||
|
///
|
||||||
|
/// These macros do not have any corresponding definition with a `macro_rules!`
|
||||||
|
/// macro, but are documented here. Their implementations can be found hardcoded
|
||||||
|
/// into libsyntax itself.
|
||||||
|
#[cfg(dox)]
|
||||||
|
pub mod builtin {
|
||||||
|
/// The core macro for formatted string creation & output.
|
||||||
|
///
|
||||||
|
/// This macro takes as its first argument a callable expression which will
|
||||||
|
/// receive as its first argument a value of type `&fmt::Arguments`. This
|
||||||
|
/// value can be passed to the functions in `std::fmt` for performing useful
|
||||||
|
/// functions. All other formatting macros (`format!`, `write!`,
|
||||||
|
/// `println!`, etc) are proxied through this one.
|
||||||
|
///
|
||||||
|
/// For more information, see the documentation in `std::fmt`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::fmt;
|
||||||
|
///
|
||||||
|
/// let s = format_args!(fmt::format, "hello {}", "world");
|
||||||
|
/// assert_eq!(s, format!("hello {}", "world"));
|
||||||
|
///
|
||||||
|
/// format_args!(|args| {
|
||||||
|
/// // pass `args` to another function, etc.
|
||||||
|
/// }, "hello {}", "world");
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! format_args( ($closure:expr, $fmt:expr $($args:tt)*) => ({
|
||||||
|
/* compiler built-in */
|
||||||
|
}) )
|
||||||
|
|
||||||
|
/// Inspect an environment variable at compile time.
|
||||||
|
///
|
||||||
|
/// This macro will expand to the value of the named environment variable at
|
||||||
|
/// compile time, yielding an expression of type `&'static str`.
|
||||||
|
///
|
||||||
|
/// If the environment variable is not defined, then a compilation error
|
||||||
|
/// will be emitted. To not emit a compile error, use the `option_env!`
|
||||||
|
/// macro instead.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let user: &'static str = env!("USER");
|
||||||
|
/// println!("the user who compiled this code is: {}", user);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! env( ($name:expr) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Optionally inspect an environment variable at compile time.
|
||||||
|
///
|
||||||
|
/// If the named environment variable is present at compile time, this will
|
||||||
|
/// expand into an expression of type `Option<&'static str>` whose value is
|
||||||
|
/// `Some` of the value of the environment variable. If the environment
|
||||||
|
/// variable is not present, then this will expand to `None`.
|
||||||
|
///
|
||||||
|
/// A compile time error is never emitted when using this macro regardless
|
||||||
|
/// of whether the environment variable is present or not.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let key: Option<&'static str> = option_env!("SECRET_KEY");
|
||||||
|
/// println!("the secret key might be: {}", key);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! option_env( ($name:expr) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Concatenate literals into a static byte slice.
|
||||||
|
///
|
||||||
|
/// This macro takes any number of comma-separated literal expressions,
|
||||||
|
/// yielding an expression of type `&'static [u8]` which is the
|
||||||
|
/// concatenation (left to right) of all the literals in their byte format.
|
||||||
|
///
|
||||||
|
/// This extension currently only supports string literals, character
|
||||||
|
/// literals, and integers less than 256. The byte slice returned is the
|
||||||
|
/// utf8-encoding of strings and characters.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let rust = bytes!("r", 'u', "st");
|
||||||
|
/// assert_eq!(rust[1], 'u' as u8);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bytes( ($($e:expr),*) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Concatenate identifiers into one identifier.
|
||||||
|
///
|
||||||
|
/// This macro takes any number of comma-separated identifiers, and
|
||||||
|
/// concatenates them all into one, yielding an expression which is a new
|
||||||
|
/// identifier. Note that hygiene makes it such that this macro cannot
|
||||||
|
/// capture local variables, and macros are only allowed in item,
|
||||||
|
/// statement or expression position, meaning this macro may be difficult to
|
||||||
|
/// use in some situations.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn foobar() -> int { 23 }
|
||||||
|
///
|
||||||
|
/// let f = concat_idents!(foo, bar);
|
||||||
|
/// println!("{}", f());
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! concat_idents( ($($e:ident),*) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Concatenates literals into a static string slice.
|
||||||
|
///
|
||||||
|
/// This macro takes any number of comma-separated literals, yielding an
|
||||||
|
/// expression of type `&'static str` which represents all of the literals
|
||||||
|
/// concatenated left-to-right.
|
||||||
|
///
|
||||||
|
/// Integer and floating point literals are stringified in order to be
|
||||||
|
/// concatenated.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let s = concat!("test", 10, 'b', true);
|
||||||
|
/// assert_eq!(s, "test10btrue");
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! concat( ($($e:expr),*) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// A macro which expands to the line number on which it was invoked.
|
||||||
|
///
|
||||||
|
/// The expanded expression has type `uint`, and the returned line is not
|
||||||
|
/// the invocation of the `line!()` macro itself, but rather the first macro
|
||||||
|
/// invocation leading up to the invocation of the `line!()` macro.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let current_line = line!();
|
||||||
|
/// println!("defined on line: {}", current_line);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! line( () => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// A macro which expands to the column number on which it was invoked.
|
||||||
|
///
|
||||||
|
/// The expanded expression has type `uint`, and the returned column is not
|
||||||
|
/// the invocation of the `col!()` macro itself, but rather the first macro
|
||||||
|
/// invocation leading up to the invocation of the `col!()` macro.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let current_col = col!();
|
||||||
|
/// println!("defined on column: {}", current_col);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! col( () => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// A macro which expands to the file name from which it was invoked.
|
||||||
|
///
|
||||||
|
/// The expanded expression has type `&'static str`, and the returned file
|
||||||
|
/// is not the invocation of the `file!()` macro itself, but rather the
|
||||||
|
/// first macro invocation leading up to the invocation of the `file!()`
|
||||||
|
/// macro.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let this_file = file!();
|
||||||
|
/// println!("defined in file: {}", this_file);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! file( () => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// A macro which stringifies its argument.
|
||||||
|
///
|
||||||
|
/// This macro will yield an expression of type `&'static str` which is the
|
||||||
|
/// stringification of all the tokens passed to the macro. No restrictions
|
||||||
|
/// are placed on the syntax of the macro invocation itself.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let one_plus_one = stringify!(1 + 1);
|
||||||
|
/// assert_eq!(one_plus_one, "1 + 1");
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! stringify( ($t:tt) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Includes a utf8-encoded file as a string.
|
||||||
|
///
|
||||||
|
/// This macro will yield an expression of type `&'static str` which is the
|
||||||
|
/// contents of the filename specified. The file is located relative to the
|
||||||
|
/// current file (similarly to how modules are found),
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// let secret_key = include_str!("secret-key.ascii");
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! include_str( ($file:expr) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Includes a file as a byte slice.
|
||||||
|
///
|
||||||
|
/// This macro will yield an expression of type `&'static [u8]` which is
|
||||||
|
/// the contents of the filename specified. The file is located relative to
|
||||||
|
/// the current file (similarly to how modules are found),
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// let secret_key = include_bin!("secret-key.bin");
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! include_bin( ($file:expr) => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Expands to a string that represents the current module path.
|
||||||
|
///
|
||||||
|
/// The current module path can be thought of as the hierarchy of modules
|
||||||
|
/// leading back up to the crate root. The first component of the path
|
||||||
|
/// returned is the name of the crate currently being compiled.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// mod test {
|
||||||
|
/// pub fn foo() {
|
||||||
|
/// assert!(module_path!().ends_with("test"));
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// test::foo();
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! module_path( () => ({ /* compiler built-in */ }) )
|
||||||
|
|
||||||
|
/// Boolean evaluation of configuration flags.
|
||||||
|
///
|
||||||
|
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
|
||||||
|
/// boolean expression evaluation of configuration flags. This frequently
|
||||||
|
/// leads to less duplicated code.
|
||||||
|
///
|
||||||
|
/// The syntax given to this macro is the same syntax as the `cfg`
|
||||||
|
/// attribute.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let my_directory = if cfg!(windows) {
|
||||||
|
/// "windows-specific-directory"
|
||||||
|
/// } else {
|
||||||
|
/// "unix-directory"
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! cfg( ($cfg:tt) => ({ /* compiler built-in */ }) )
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user