mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
Merge #5100
5100: Add support for include_str r=edwin0cheng a=lnicola r? @edwin0cheng Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
This commit is contained in:
commit
446fd3f515
@ -99,6 +99,7 @@ register_builtin! {
|
|||||||
EAGER:
|
EAGER:
|
||||||
(concat, Concat) => concat_expand,
|
(concat, Concat) => concat_expand,
|
||||||
(include, Include) => include_expand,
|
(include, Include) => include_expand,
|
||||||
|
(include_str, IncludeStr) => include_str_expand,
|
||||||
(env, Env) => env_expand,
|
(env, Env) => env_expand,
|
||||||
(option_env, OptionEnv) => option_env_expand
|
(option_env, OptionEnv) => option_env_expand
|
||||||
}
|
}
|
||||||
@ -292,11 +293,16 @@ fn concat_expand(
|
|||||||
Ok((quote!(#text), FragmentKind::Expr))
|
Ok((quote!(#text), FragmentKind::Expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option<FileId> {
|
fn relative_file(
|
||||||
|
db: &dyn AstDatabase,
|
||||||
|
call_id: MacroCallId,
|
||||||
|
path: &str,
|
||||||
|
allow_recursion: bool,
|
||||||
|
) -> Option<FileId> {
|
||||||
let call_site = call_id.as_file().original_file(db);
|
let call_site = call_id.as_file().original_file(db);
|
||||||
let res = db.resolve_path(call_site, path)?;
|
let res = db.resolve_path(call_site, path)?;
|
||||||
// Prevent include itself
|
// Prevent include itself
|
||||||
if res == call_site {
|
if res == call_site && !allow_recursion {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(res)
|
Some(res)
|
||||||
@ -319,8 +325,8 @@ fn include_expand(
|
|||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
|
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
|
||||||
let path = parse_string(tt)?;
|
let path = parse_string(tt)?;
|
||||||
let file_id =
|
let file_id = relative_file(db, arg_id.into(), &path, false)
|
||||||
relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?;
|
.ok_or_else(|| mbe::ExpandError::ConversionError)?;
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// Handle include as expression
|
// Handle include as expression
|
||||||
@ -331,6 +337,30 @@ fn include_expand(
|
|||||||
Ok((res, FragmentKind::Items))
|
Ok((res, FragmentKind::Items))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn include_str_expand(
|
||||||
|
db: &dyn AstDatabase,
|
||||||
|
arg_id: EagerMacroId,
|
||||||
|
tt: &tt::Subtree,
|
||||||
|
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
|
||||||
|
let path = parse_string(tt)?;
|
||||||
|
|
||||||
|
// FIXME: we're not able to read excluded files (which is most of them because
|
||||||
|
// it's unusual to `include_str!` a Rust file), but we can return an empty string.
|
||||||
|
// Ideally, we'd be able to offer a precise expansion if the user asks for macro
|
||||||
|
// expansion.
|
||||||
|
let file_id = match relative_file(db, arg_id.into(), &path, true) {
|
||||||
|
Some(file_id) => file_id,
|
||||||
|
None => {
|
||||||
|
return Ok((quote!(""), FragmentKind::Expr));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let text = db.file_text(file_id);
|
||||||
|
let text = &*text;
|
||||||
|
|
||||||
|
Ok((quote!(#text), FragmentKind::Expr))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
|
fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
|
||||||
let krate = db.lookup_intern_eager_expansion(arg_id).krate;
|
let krate = db.lookup_intern_eager_expansion(arg_id).krate;
|
||||||
db.crate_graph()[krate].env.get(key)
|
db.crate_graph()[krate].env.get(key)
|
||||||
|
@ -191,6 +191,7 @@ pub mod known {
|
|||||||
stringify,
|
stringify,
|
||||||
concat,
|
concat,
|
||||||
include,
|
include,
|
||||||
|
include_str,
|
||||||
format_args,
|
format_args,
|
||||||
format_args_nl,
|
format_args_nl,
|
||||||
env,
|
env,
|
||||||
|
@ -494,6 +494,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
//- /src/main.rs
|
//- /src/main.rs
|
||||||
#[rustc_builtin_macro] macro_rules! include {}
|
#[rustc_builtin_macro] macro_rules! include {}
|
||||||
|
#[rustc_builtin_macro] macro_rules! include_str {}
|
||||||
#[rustc_builtin_macro] macro_rules! concat {}
|
#[rustc_builtin_macro] macro_rules! concat {}
|
||||||
#[rustc_builtin_macro] macro_rules! env {}
|
#[rustc_builtin_macro] macro_rules! env {}
|
||||||
|
|
||||||
@ -512,6 +513,7 @@ fn main() {
|
|||||||
let va = A;
|
let va = A;
|
||||||
let vb = B;
|
let vb = B;
|
||||||
let should_be_str = message();
|
let should_be_str = message();
|
||||||
|
let another_str = include_str!("main.rs");
|
||||||
}
|
}
|
||||||
"###,
|
"###,
|
||||||
)
|
)
|
||||||
@ -523,36 +525,19 @@ fn main() {
|
|||||||
let res = server.send_request::<HoverRequest>(HoverParams {
|
let res = server.send_request::<HoverRequest>(HoverParams {
|
||||||
text_document_position_params: TextDocumentPositionParams::new(
|
text_document_position_params: TextDocumentPositionParams::new(
|
||||||
server.doc_id("src/main.rs"),
|
server.doc_id("src/main.rs"),
|
||||||
Position::new(18, 10),
|
Position::new(19, 10),
|
||||||
|
),
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
});
|
||||||
|
assert!(res.to_string().contains("&str"));
|
||||||
|
let res = server.send_request::<HoverRequest>(HoverParams {
|
||||||
|
text_document_position_params: TextDocumentPositionParams::new(
|
||||||
|
server.doc_id("src/main.rs"),
|
||||||
|
Position::new(20, 10),
|
||||||
),
|
),
|
||||||
work_done_progress_params: Default::default(),
|
work_done_progress_params: Default::default(),
|
||||||
});
|
});
|
||||||
assert!(res.to_string().contains("&str"));
|
assert!(res.to_string().contains("&str"));
|
||||||
server.request::<GotoTypeDefinition>(
|
|
||||||
GotoDefinitionParams {
|
|
||||||
text_document_position_params: TextDocumentPositionParams::new(
|
|
||||||
server.doc_id("src/main.rs"),
|
|
||||||
Position::new(16, 9),
|
|
||||||
),
|
|
||||||
work_done_progress_params: Default::default(),
|
|
||||||
partial_result_params: Default::default(),
|
|
||||||
},
|
|
||||||
json!([{
|
|
||||||
"originSelectionRange": {
|
|
||||||
"end": { "character": 10, "line": 16 },
|
|
||||||
"start": { "character": 8, "line": 16 }
|
|
||||||
},
|
|
||||||
"targetRange": {
|
|
||||||
"end": { "character": 9, "line": 7 },
|
|
||||||
"start": { "character": 0, "line": 6 }
|
|
||||||
},
|
|
||||||
"targetSelectionRange": {
|
|
||||||
"end": { "character": 8, "line": 7 },
|
|
||||||
"start": { "character": 7, "line": 7 }
|
|
||||||
},
|
|
||||||
"targetUri": "file:///[..]src/main.rs"
|
|
||||||
}]),
|
|
||||||
);
|
|
||||||
server.request::<GotoTypeDefinition>(
|
server.request::<GotoTypeDefinition>(
|
||||||
GotoDefinitionParams {
|
GotoDefinitionParams {
|
||||||
text_document_position_params: TextDocumentPositionParams::new(
|
text_document_position_params: TextDocumentPositionParams::new(
|
||||||
@ -568,12 +553,37 @@ fn main() {
|
|||||||
"start": { "character": 8, "line": 17 }
|
"start": { "character": 8, "line": 17 }
|
||||||
},
|
},
|
||||||
"targetRange": {
|
"targetRange": {
|
||||||
"end": { "character": 9, "line": 11 },
|
"end": { "character": 9, "line": 8 },
|
||||||
"start": { "character": 0, "line":10 }
|
"start": { "character": 0, "line": 7 }
|
||||||
},
|
},
|
||||||
"targetSelectionRange": {
|
"targetSelectionRange": {
|
||||||
"end": { "character": 8, "line": 11 },
|
"end": { "character": 8, "line": 8 },
|
||||||
"start": { "character": 7, "line": 11 }
|
"start": { "character": 7, "line": 8 }
|
||||||
|
},
|
||||||
|
"targetUri": "file:///[..]src/main.rs"
|
||||||
|
}]),
|
||||||
|
);
|
||||||
|
server.request::<GotoTypeDefinition>(
|
||||||
|
GotoDefinitionParams {
|
||||||
|
text_document_position_params: TextDocumentPositionParams::new(
|
||||||
|
server.doc_id("src/main.rs"),
|
||||||
|
Position::new(18, 9),
|
||||||
|
),
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
partial_result_params: Default::default(),
|
||||||
|
},
|
||||||
|
json!([{
|
||||||
|
"originSelectionRange": {
|
||||||
|
"end": { "character": 10, "line": 18 },
|
||||||
|
"start": { "character": 8, "line": 18 }
|
||||||
|
},
|
||||||
|
"targetRange": {
|
||||||
|
"end": { "character": 9, "line": 12 },
|
||||||
|
"start": { "character": 0, "line":11 }
|
||||||
|
},
|
||||||
|
"targetSelectionRange": {
|
||||||
|
"end": { "character": 8, "line": 12 },
|
||||||
|
"start": { "character": 7, "line": 12 }
|
||||||
},
|
},
|
||||||
"targetUri": "file:///[..]src/main.rs"
|
"targetUri": "file:///[..]src/main.rs"
|
||||||
}]),
|
}]),
|
||||||
|
Loading…
Reference in New Issue
Block a user