1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use codemap
::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}
;
17 use parse
::token
::InternedString
;
18 use parse
::token
::special_idents
;
19 use parse
::{token, ParseSess}
;
21 use util
::small_vector
::SmallVector
;
23 /// Craft a span that will be ignored by the stability lint's
24 /// call to codemap's is_internal check.
25 /// The expanded code uses the unstable `#[prelude_import]` attribute.
26 fn ignored_span(sess
: &ParseSess
, sp
: Span
) -> Span
{
30 name
: "std_inject".to_string(),
31 format
: MacroAttribute
,
33 allow_internal_unstable
: true,
36 let expn_id
= sess
.codemap().record_expansion(info
);
42 pub fn maybe_inject_crates_ref(krate
: ast
::Crate
, alt_std_name
: Option
<String
>)
45 inject_crates_ref(krate
, alt_std_name
)
51 pub fn maybe_inject_prelude(sess
: &ParseSess
, krate
: ast
::Crate
) -> ast
::Crate
{
53 let mut fold
= PreludeInjector
{
54 span
: ignored_span(sess
, DUMMY_SP
)
56 fold
.fold_crate(krate
)
62 pub fn use_std(krate
: &ast
::Crate
) -> bool
{
63 !attr
::contains_name(&krate
.attrs
, "no_std")
66 fn no_prelude(attrs
: &[ast
::Attribute
]) -> bool
{
67 attr
::contains_name(attrs
, "no_implicit_prelude")
70 struct StandardLibraryInjector
{
71 alt_std_name
: Option
<String
>,
74 impl fold
::Folder
for StandardLibraryInjector
{
75 fn fold_crate(&mut self, mut krate
: ast
::Crate
) -> ast
::Crate
{
77 // The name to use in `extern crate name as std;`
78 let actual_crate_name
= match self.alt_std_name
{
79 Some(ref s
) => token
::intern(&s
),
80 None
=> token
::intern("std"),
83 krate
.module
.items
.insert(0, P(ast
::Item
{
84 id
: ast
::DUMMY_NODE_ID
,
85 ident
: token
::str_to_ident("std"),
87 attr
::mk_attr_outer(attr
::mk_attr_id(), attr
::mk_word_item(
88 InternedString
::new("macro_use")))),
89 node
: ast
::ItemExternCrate(Some(actual_crate_name
)),
98 fn inject_crates_ref(krate
: ast
::Crate
, alt_std_name
: Option
<String
>) -> ast
::Crate
{
99 let mut fold
= StandardLibraryInjector
{
100 alt_std_name
: alt_std_name
102 fold
.fold_crate(krate
)
105 struct PreludeInjector
{
109 impl fold
::Folder
for PreludeInjector
{
110 fn fold_crate(&mut self, mut krate
: ast
::Crate
) -> ast
::Crate
{
111 // only add `use std::prelude::*;` if there wasn't a
112 // `#![no_implicit_prelude]` at the crate level.
113 // fold_mod() will insert glob path.
114 if !no_prelude(&krate
.attrs
) {
115 krate
.module
= self.fold_mod(krate
.module
);
120 fn fold_item(&mut self, item
: P
<ast
::Item
>) -> SmallVector
<P
<ast
::Item
>> {
121 if !no_prelude(&item
.attrs
) {
122 // only recur if there wasn't `#![no_implicit_prelude]`
123 // on this item, i.e. this means that the prelude is not
124 // implicitly imported though the whole subtree
125 fold
::noop_fold_item(item
, self)
127 SmallVector
::one(item
)
131 fn fold_mod(&mut self, mut mod_
: ast
::Mod
) -> ast
::Mod
{
132 let prelude_path
= ast
::Path
{
137 identifier
: token
::str_to_ident("std"),
138 parameters
: ast
::PathParameters
::none(),
141 identifier
: token
::str_to_ident("prelude"),
142 parameters
: ast
::PathParameters
::none(),
145 identifier
: token
::str_to_ident("v1"),
146 parameters
: ast
::PathParameters
::none(),
151 let vp
= P(codemap
::dummy_spanned(ast
::ViewPathGlob(prelude_path
)));
152 mod_
.items
.insert(0, P(ast
::Item
{
153 id
: ast
::DUMMY_NODE_ID
,
154 ident
: special_idents
::invalid
,
155 node
: ast
::ItemUse(vp
),
156 attrs
: vec
![ast
::Attribute
{
158 node
: ast
::Attribute_
{
159 id
: attr
::mk_attr_id(),
160 style
: ast
::AttrOuter
,
161 value
: P(ast
::MetaItem
{
163 node
: ast
::MetaWord(special_idents
::prelude_import
.name
.as_str()),
165 is_sugared_doc
: false,
172 fold
::noop_fold_mod(mod_
, self)