Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0ba15c99
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0ba15c99
编写于
7月 04, 2014
作者:
J
John Clements
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hygiene for item fn args
also, introduce fn_decl_arg_bindings and expand_and_rename abstractions
上级
92708322
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
49 addition
and
7 deletion
+49
-7
src/libsyntax/ext/expand.rs
src/libsyntax/ext/expand.rs
+49
-7
未找到文件。
src/libsyntax/ext/expand.rs
浏览文件 @
0ba15c99
...
...
@@ -386,6 +386,19 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
expand_item_modifiers
(
it
,
fld
)
}
/// Expand item_underscore
fn
expand_item_underscore
(
item
:
&
ast
::
Item_
,
fld
:
&
mut
MacroExpander
)
->
ast
::
Item_
{
match
*
item
{
ast
::
ItemFn
(
decl
,
fn_style
,
abi
,
ref
generics
,
body
)
=>
{
let
(
rewritten_fn_decl
,
rewritten_body
)
=
expand_and_rename_fn_decl_and_block
(
decl
,
body
,
fld
);
let
expanded_generics
=
fold
::
fold_generics
(
generics
,
fld
);
ast
::
ItemFn
(
rewritten_fn_decl
,
fn_style
,
abi
,
expanded_generics
,
rewritten_body
)
}
_
=>
noop_fold_item_underscore
(
&*
item
,
fld
)
}
}
// does this attribute list contain "macro_escape" ?
fn
contains_macro_escape
(
attrs
:
&
[
ast
::
Attribute
])
->
bool
{
attr
::
contains_name
(
attrs
,
"macro_escape"
)
...
...
@@ -656,6 +669,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
}
}
// expand the arm of a 'match', renaming for macro hygiene
fn
expand_arm
(
arm
:
&
ast
::
Arm
,
fld
:
&
mut
MacroExpander
)
->
ast
::
Arm
{
// expand pats... they might contain macro uses:
let
expanded_pats
:
Vec
<
Gc
<
ast
::
Pat
>>
=
arm
.pats
.iter
()
.map
(|
pat
|
fld
.fold_pat
(
*
pat
))
.collect
();
...
...
@@ -665,17 +679,15 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// all of the pats must have the same set of bindings, so use the
// first one to extract them and generate new names:
let
first_pat
=
expanded_pats
.get
(
0
);
// code duplicated from 'let', above. Perhaps this can be lifted
// into a separate function:
let
idents
=
pattern_bindings
(
*
first_pat
);
let
new_
pending_
renames
=
let
new_renames
=
idents
.iter
()
.map
(|
id
|
(
*
id
,
fresh_name
(
id
)))
.collect
();
// apply the renaming, but only to the PatIdents:
let
mut
rename_pats_fld
=
PatIdentRenamer
{
renames
:
&
new_
pending_
renames
};
let
mut
rename_pats_fld
=
PatIdentRenamer
{
renames
:
&
new_renames
};
let
rewritten_pats
=
expanded_pats
.iter
()
.map
(|
pat
|
rename_pats_fld
.fold_pat
(
*
pat
))
.collect
();
// apply renaming and then expansion to the guard and the body:
let
mut
rename_fld
=
IdentRenamer
{
renames
:
&
new_
pending_
renames
};
let
mut
rename_fld
=
IdentRenamer
{
renames
:
&
new_renames
};
let
rewritten_guard
=
arm
.guard
.map
(|
g
|
fld
.fold_expr
(
rename_fld
.fold_expr
(
g
)));
let
rewritten_body
=
fld
.fold_expr
(
rename_fld
.fold_expr
(
arm
.body
));
...
...
@@ -687,8 +699,6 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
}
}
/// A visitor that extracts the PatIdent (binding) paths
/// from a given thingy and puts them in a mutable
/// array
...
...
@@ -721,6 +731,15 @@ fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
name_finder
.ident_accumulator
}
/// find the PatIdent paths in a
fn
fn_decl_arg_bindings
(
fn_decl
:
&
ast
::
FnDecl
)
->
Vec
<
ast
::
Ident
>
{
let
mut
pat_idents
=
PatIdentFinder
{
ident_accumulator
:
Vec
::
new
()};
for
arg
in
fn_decl
.inputs
.iter
()
{
pat_idents
.visit_pat
(
arg
.pat
,());
}
pat_idents
.ident_accumulator
}
// expand a block. pushes a new exts_frame, then calls expand_block_elts
fn
expand_block
(
blk
:
&
Block
,
fld
:
&
mut
MacroExpander
)
->
P
<
Block
>
{
// see note below about treatment of exts table
...
...
@@ -882,6 +901,25 @@ fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
}
}
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block.
fn
expand_and_rename_fn_decl_and_block
(
fn_decl
:
&
ast
::
FnDecl
,
block
:
Gc
<
ast
::
Block
>
,
fld
:
&
mut
MacroExpander
)
->
(
Gc
<
ast
::
FnDecl
>
,
Gc
<
ast
::
Block
>
)
{
let
expanded_decl
=
fld
.fold_fn_decl
(
fn_decl
);
let
idents
=
fn_decl_arg_bindings
(
expanded_decl
);
let
renames
=
idents
.iter
()
.map
(|
id
:
&
ast
::
Ident
|
(
*
id
,
fresh_name
(
id
)))
.collect
();
// first, a renamer for the PatIdents, for the fn_decl:
let
mut
rename_pat_fld
=
PatIdentRenamer
{
renames
:
&
renames
};
let
rewritten_fn_decl
=
rename_pat_fld
.fold_fn_decl
(
expanded_decl
);
// now, a renamer for *all* idents, for the body:
let
mut
rename_fld
=
IdentRenamer
{
renames
:
&
renames
};
let
rewritten_body
=
fld
.fold_block
(
rename_fld
.fold_block
(
block
));
(
rewritten_fn_decl
,
rewritten_body
)
}
/// A tree-folder that performs macro expansion
pub
struct
MacroExpander
<
'a
,
'b
>
{
pub
extsbox
:
SyntaxEnv
,
...
...
@@ -901,6 +939,10 @@ fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
expand_item
(
item
,
self
)
}
fn
fold_item_underscore
(
&
mut
self
,
item
:
&
ast
::
Item_
)
->
ast
::
Item_
{
expand_item_underscore
(
item
,
self
)
}
fn
fold_stmt
(
&
mut
self
,
stmt
:
&
ast
::
Stmt
)
->
SmallVector
<
Gc
<
ast
::
Stmt
>>
{
expand_stmt
(
stmt
,
self
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录