Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
15994612
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
15994612
编写于
9月 20, 2016
作者:
J
Jeffrey Seyfried
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor `ext::tt::macro_rules::compile` to take a `ParseSess` instead of an `ExtCtxt`.
上级
ee959a8c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
33 addition
and
40 deletion
+33
-40
src/libsyntax/ext/base.rs
src/libsyntax/ext/base.rs
+1
-1
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/macro_rules.rs
+32
-39
未找到文件。
src/libsyntax/ext/base.rs
浏览文件 @
15994612
...
...
@@ -816,7 +816,7 @@ pub fn insert_macro(&mut self, def: ast::MacroDef) {
self
.exported_macros
.push
(
def
.clone
());
}
if
def
.use_locally
{
let
ext
=
macro_rules
::
compile
(
self
,
&
def
);
let
ext
=
macro_rules
::
compile
(
self
.parse_sess
,
&
def
);
self
.resolver
.add_macro
(
self
.current_expansion.mark
,
def
.ident
,
Rc
::
new
(
ext
));
}
}
...
...
src/libsyntax/ext/tt/macro_rules.rs
浏览文件 @
15994612
...
...
@@ -16,6 +16,7 @@
use
ext
::
tt
::
macro_parser
::{
Success
,
Error
,
Failure
};
use
ext
::
tt
::
macro_parser
::{
MatchedSeq
,
MatchedNonterminal
};
use
ext
::
tt
::
macro_parser
::
parse
;
use
parse
::
ParseSess
;
use
parse
::
lexer
::
new_tt_reader
;
use
parse
::
parser
::{
Parser
,
Restrictions
};
use
parse
::
token
::{
self
,
gensym_ident
,
NtTT
,
Token
};
...
...
@@ -204,7 +205,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
_
=>
cx
.span_bug
(
sp
,
"malformed macro rhs"
),
};
// rhs has holes ( `$id` and `$(...)` that need filled)
let
trncbr
=
new_tt_reader
(
&
cx
.parse_sess
()
.span_diagnostic
,
let
trncbr
=
new_tt_reader
(
&
cx
.parse_sess.span_diagnostic
,
Some
(
named_matches
),
imported_from
,
rhs
);
...
...
@@ -278,9 +279,7 @@ fn expand(&self,
// Holy self-referential!
/// Converts a `macro_rules!` invocation into a syntax extension.
pub
fn
compile
<
'cx
>
(
cx
:
&
'cx
mut
ExtCtxt
,
def
:
&
ast
::
MacroDef
)
->
SyntaxExtension
{
pub
fn
compile
(
sess
:
&
ParseSess
,
def
:
&
ast
::
MacroDef
)
->
SyntaxExtension
{
let
lhs_nm
=
gensym_ident
(
"lhs"
);
let
rhs_nm
=
gensym_ident
(
"rhs"
);
...
...
@@ -312,19 +311,12 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
];
// Parse the macro_rules! invocation (`none` is for no interpolations):
let
arg_reader
=
new_tt_reader
(
&
cx
.parse_sess
()
.span_diagnostic
,
None
,
None
,
def
.body
.clone
());
let
argument_map
=
match
parse
(
cx
.parse_sess
(),
cx
.cfg
(),
arg_reader
,
&
argument_gram
)
{
let
arg_reader
=
new_tt_reader
(
&
sess
.span_diagnostic
,
None
,
None
,
def
.body
.clone
());
let
argument_map
=
match
parse
(
sess
,
Vec
::
new
(),
arg_reader
,
&
argument_gram
)
{
Success
(
m
)
=>
m
,
Failure
(
sp
,
str
)
|
Error
(
sp
,
str
)
=>
{
panic!
(
cx
.parse_sess
()
.span_diagnostic
.span_fatal
(
sp
.substitute_dummy
(
def
.span
),
&
str
[
..
]));
panic!
(
sess
.span_diagnostic
.span_fatal
(
sp
.substitute_dummy
(
def
.span
),
&
str
));
}
};
...
...
@@ -335,27 +327,27 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
MatchedSeq
(
ref
s
,
_
)
=>
{
s
.iter
()
.map
(|
m
|
match
**
m
{
MatchedNonterminal
(
NtTT
(
ref
tt
))
=>
{
valid
&=
check_lhs_nt_follows
(
cx
,
tt
);
valid
&=
check_lhs_nt_follows
(
sess
,
tt
);
(
**
tt
)
.clone
()
}
_
=>
cx
.span_bug
(
def
.span
,
"wrong-structured lhs"
)
_
=>
sess
.span_diagnostic
.span_bug
(
def
.span
,
"wrong-structured lhs"
)
})
.collect
()
}
_
=>
cx
.span_bug
(
def
.span
,
"wrong-structured lhs"
)
_
=>
sess
.span_diagnostic
.span_bug
(
def
.span
,
"wrong-structured lhs"
)
};
let
rhses
=
match
**
argument_map
.get
(
&
rhs_nm
)
.unwrap
()
{
MatchedSeq
(
ref
s
,
_
)
=>
{
s
.iter
()
.map
(|
m
|
match
**
m
{
MatchedNonterminal
(
NtTT
(
ref
tt
))
=>
(
**
tt
)
.clone
(),
_
=>
cx
.span_bug
(
def
.span
,
"wrong-structured rhs"
)
_
=>
sess
.span_diagnostic
.span_bug
(
def
.span
,
"wrong-structured rhs"
)
})
.collect
()
}
_
=>
cx
.span_bug
(
def
.span
,
"wrong-structured rhs"
)
_
=>
sess
.span_diagnostic
.span_bug
(
def
.span
,
"wrong-structured rhs"
)
};
for
rhs
in
&
rhses
{
valid
&=
check_rhs
(
cx
,
rhs
);
valid
&=
check_rhs
(
sess
,
rhs
);
}
let
exp
:
Box
<
_
>
=
Box
::
new
(
MacroRulesMacroExpander
{
...
...
@@ -369,14 +361,14 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
NormalTT
(
exp
,
Some
(
def
.span
),
def
.allow_internal_unstable
)
}
fn
check_lhs_nt_follows
(
cx
:
&
mut
ExtCtxt
,
lhs
:
&
TokenTree
)
->
bool
{
fn
check_lhs_nt_follows
(
sess
:
&
ParseSess
,
lhs
:
&
TokenTree
)
->
bool
{
// lhs is going to be like TokenTree::Delimited(...), where the
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
match
lhs
{
&
TokenTree
::
Delimited
(
_
,
ref
tts
)
=>
check_matcher
(
cx
,
&
tts
.tts
),
&
TokenTree
::
Delimited
(
_
,
ref
tts
)
=>
check_matcher
(
sess
,
&
tts
.tts
),
_
=>
{
cx
.span_err
(
lhs
.get_span
(),
"invalid macro matcher; matchers must
\
be contained in balanced delimiters"
);
let
msg
=
"invalid macro matcher; matchers must be contained in balanced delimiters"
;
sess
.span_diagnostic
.span_err
(
lhs
.get_span
(),
msg
);
false
}
}
...
...
@@ -384,20 +376,20 @@ fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &TokenTree) -> bool {
// after parsing/expansion. we can report every error in every macro this way.
}
fn
check_rhs
(
cx
:
&
mut
ExtCtxt
,
rhs
:
&
TokenTree
)
->
bool
{
fn
check_rhs
(
sess
:
&
ParseSess
,
rhs
:
&
TokenTree
)
->
bool
{
match
*
rhs
{
TokenTree
::
Delimited
(
..
)
=>
return
true
,
_
=>
cx
.span_err
(
rhs
.get_span
(),
"macro rhs must be delimited"
)
_
=>
sess
.span_diagnostic
.span_err
(
rhs
.get_span
(),
"macro rhs must be delimited"
)
}
false
}
fn
check_matcher
(
cx
:
&
mut
ExtCtxt
,
matcher
:
&
[
TokenTree
])
->
bool
{
fn
check_matcher
(
sess
:
&
ParseSess
,
matcher
:
&
[
TokenTree
])
->
bool
{
let
first_sets
=
FirstSets
::
new
(
matcher
);
let
empty_suffix
=
TokenSet
::
empty
();
let
err
=
cx
.parse_
sess.span_diagnostic
.err_count
();
check_matcher_core
(
cx
,
&
first_sets
,
matcher
,
&
empty_suffix
);
err
==
cx
.parse_
sess.span_diagnostic
.err_count
()
let
err
=
sess
.span_diagnostic
.err_count
();
check_matcher_core
(
sess
,
&
first_sets
,
matcher
,
&
empty_suffix
);
err
==
sess
.span_diagnostic
.err_count
()
}
// The FirstSets for a matcher is a mapping from subsequences in the
...
...
@@ -635,7 +627,7 @@ fn add_all(&mut self, other: &Self) {
//
// Requires that `first_sets` is pre-computed for `matcher`;
// see `FirstSets::new`.
fn
check_matcher_core
(
cx
:
&
mut
ExtCtxt
,
fn
check_matcher_core
(
sess
:
&
ParseSess
,
first_sets
:
&
FirstSets
,
matcher
:
&
[
TokenTree
],
follow
:
&
TokenSet
)
->
TokenSet
{
...
...
@@ -667,7 +659,8 @@ fn check_matcher_core(cx: &mut ExtCtxt,
TokenTree
::
Token
(
sp
,
ref
tok
)
=>
{
let
can_be_followed_by_any
;
if
let
Err
(
bad_frag
)
=
has_legal_fragment_specifier
(
tok
)
{
cx
.struct_span_err
(
sp
,
&
format!
(
"invalid fragment specifier `{}`"
,
bad_frag
))
let
msg
=
format!
(
"invalid fragment specifier `{}`"
,
bad_frag
);
sess
.span_diagnostic
.struct_span_err
(
sp
,
&
msg
)
.help
(
"valid fragment specifiers are `ident`, `block`,
\
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt`
\
and `item`"
)
...
...
@@ -692,7 +685,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
}
TokenTree
::
Delimited
(
_
,
ref
d
)
=>
{
let
my_suffix
=
TokenSet
::
singleton
((
d
.close_span
,
Token
::
CloseDelim
(
d
.delim
)));
check_matcher_core
(
cx
,
first_sets
,
&
d
.tts
,
&
my_suffix
);
check_matcher_core
(
sess
,
first_sets
,
&
d
.tts
,
&
my_suffix
);
// don't track non NT tokens
last
.replace_with_irrelevant
();
...
...
@@ -724,7 +717,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
// At this point, `suffix_first` is built, and
// `my_suffix` is some TokenSet that we can use
// for checking the interior of `seq_rep`.
let
next
=
check_matcher_core
(
cx
,
first_sets
,
&
seq_rep
.tts
,
my_suffix
);
let
next
=
check_matcher_core
(
sess
,
first_sets
,
&
seq_rep
.tts
,
my_suffix
);
if
next
.maybe_empty
{
last
.add_all
(
&
next
);
}
else
{
...
...
@@ -744,9 +737,9 @@ fn check_matcher_core(cx: &mut ExtCtxt,
'each_last
:
for
&
(
_
sp
,
ref
t
)
in
&
last
.tokens
{
if
let
MatchNt
(
ref
name
,
ref
frag_spec
)
=
*
t
{
for
&
(
sp
,
ref
next_token
)
in
&
suffix_first
.tokens
{
match
is_in_follow
(
cx
,
next_token
,
&
frag_spec
.name
.as_str
())
{
match
is_in_follow
(
next_token
,
&
frag_spec
.name
.as_str
())
{
Err
((
msg
,
help
))
=>
{
cx
.struct_span_err
(
sp
,
&
msg
)
.help
(
help
)
.emit
();
sess
.span_diagnostic
.struct_span_err
(
sp
,
&
msg
)
.help
(
help
)
.emit
();
// don't bother reporting every source of
// conflict for a particular element of `last`.
continue
'each_last
;
...
...
@@ -761,7 +754,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
"may be"
};
cx
.span_err
(
sess
.span_diagnostic
.span_err
(
sp
,
&
format!
(
"`${name}:{frag}` {may_be} followed by `{next}`, which
\
is not allowed for `{frag}` fragments"
,
...
...
@@ -818,7 +811,7 @@ fn frag_can_be_followed_by_any(frag: &str) -> bool {
/// break macros that were relying on that binary operator as a
/// separator.
// when changing this do not forget to update doc/book/macros.md!
fn
is_in_follow
(
_
:
&
ExtCtxt
,
tok
:
&
Token
,
frag
:
&
str
)
->
Result
<
bool
,
(
String
,
&
'static
str
)
>
{
fn
is_in_follow
(
tok
:
&
Token
,
frag
:
&
str
)
->
Result
<
bool
,
(
String
,
&
'static
str
)
>
{
if
let
&
CloseDelim
(
_
)
=
tok
{
// closing a token tree can never be matched by any fragment;
// iow, we always require that `(` and `)` match, etc.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录