Re-implement rust string highlighting via tool attribute

This commit is contained in:
Lukas Wirth 2025-01-10 13:49:35 +01:00
parent 897f7e579e
commit bf669dab84
72 changed files with 386 additions and 173 deletions

View file

@ -345,7 +345,7 @@ mod tests {
}
}
fn do_check(ra_fixture: &str, expected: &[&str]) {
fn do_check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &[&str]) {
let (offset, code) = extract_offset(ra_fixture);
let code = {
let mut buf = String::new();
@ -509,7 +509,7 @@ fn foo() {
);
}
fn do_check_local_name(ra_fixture: &str, expected_offset: u32) {
fn do_check_local_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_offset: u32) {
let (db, position) = TestDB::with_position(ra_fixture);
let file_id = position.file_id;
let offset = position.offset;

View file

@ -7,7 +7,7 @@ use crate::{test_db::TestDB, ModuleDefId};
use super::*;
fn lower(ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) {
fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) {
let db = TestDB::with_files(ra_fixture);
let krate = db.fetch_test_crate();
@ -27,14 +27,14 @@ fn lower(ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) {
(db, body, fn_def)
}
fn def_map_at(ra_fixture: &str) -> String {
fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
let (db, position) = TestDB::with_position(ra_fixture);
let module = db.module_at_position(position);
module.def_map(&db).dump(&db)
}
fn check_block_scopes_at(ra_fixture: &str, expect: Expect) {
fn check_block_scopes_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, position) = TestDB::with_position(ra_fixture);
let module = db.module_at_position(position);
@ -42,7 +42,7 @@ fn check_block_scopes_at(ra_fixture: &str, expect: Expect) {
expect.assert_eq(&actual);
}
fn check_at(ra_fixture: &str, expect: Expect) {
fn check_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let actual = def_map_at(ra_fixture);
expect.assert_eq(&actual);
}

View file

@ -665,7 +665,7 @@ mod tests {
/// module the cursor is in.
#[track_caller]
fn check_found_path_(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
path: &str,
prefer_prelude: bool,
prefer_absolute: bool,
@ -727,19 +727,35 @@ mod tests {
expect.assert_eq(&res);
}
fn check_found_path(ra_fixture: &str, path: &str, expect: Expect) {
fn check_found_path(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
path: &str,
expect: Expect,
) {
check_found_path_(ra_fixture, path, false, false, false, expect);
}
fn check_found_path_prelude(ra_fixture: &str, path: &str, expect: Expect) {
fn check_found_path_prelude(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
path: &str,
expect: Expect,
) {
check_found_path_(ra_fixture, path, true, false, false, expect);
}
fn check_found_path_absolute(ra_fixture: &str, path: &str, expect: Expect) {
fn check_found_path_absolute(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
path: &str,
expect: Expect,
) {
check_found_path_(ra_fixture, path, false, true, false, expect);
}
fn check_found_path_prefer_no_std(ra_fixture: &str, path: &str, expect: Expect) {
fn check_found_path_prefer_no_std(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
path: &str,
expect: Expect,
) {
check_found_path_(ra_fixture, path, false, false, true, expect);
}

View file

@ -509,7 +509,12 @@ mod tests {
}
}
fn check_search(ra_fixture: &str, crate_name: &str, query: Query, expect: Expect) {
fn check_search(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
crate_name: &str,
query: Query,
expect: Expect,
) {
let db = TestDB::with_files(ra_fixture);
let crate_graph = db.crate_graph();
let krate = crate_graph
@ -587,7 +592,7 @@ mod tests {
))
}
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let db = TestDB::with_files(ra_fixture);
let crate_graph = db.crate_graph();

View file

@ -4,7 +4,7 @@ use test_fixture::WithFixture;
use crate::{db::DefDatabase, test_db::TestDB};
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, file_id) = TestDB::with_single_file(ra_fixture);
let item_tree = db.file_item_tree(file_id.into());
let pretty = item_tree.pretty_print(&db, Edition::CURRENT);

View file

@ -47,7 +47,7 @@ use crate::{
};
#[track_caller]
fn check_errors(ra_fixture: &str, expect: Expect) {
fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let db = TestDB::with_files(ra_fixture);
let krate = db.fetch_test_crate();
let def_map = db.crate_def_map(krate);
@ -77,7 +77,7 @@ fn check_errors(ra_fixture: &str, expect: Expect) {
}
#[track_caller]
fn check(ra_fixture: &str, mut expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) {
let extra_proc_macros = vec![(
r#"
#[proc_macro_attribute]

View file

@ -11,19 +11,19 @@ use triomphe::Arc;
use crate::{db::DefDatabase, nameres::DefMap, test_db::TestDB};
fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> {
fn compute_crate_def_map(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Arc<DefMap> {
let db = TestDB::with_files(ra_fixture);
let krate = db.fetch_test_crate();
db.crate_def_map(krate)
}
fn render_crate_def_map(ra_fixture: &str) -> String {
fn render_crate_def_map(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
let db = TestDB::with_files(ra_fixture);
let krate = db.fetch_test_crate();
db.crate_def_map(krate).dump(&db)
}
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let actual = render_crate_def_map(ra_fixture);
expect.assert_eq(&actual);
}

View file

@ -532,7 +532,7 @@ mod tests {
}
#[track_caller]
fn check(ra_fixture: &str, mut expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) {
let parsed = syntax::SourceFile::parse(ra_fixture, span::Edition::CURRENT);
let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(EditionedFileId::new(
FileId::from_raw(0),

View file

@ -31,7 +31,10 @@ fn simplify(e: ConstEvalError) -> ConstEvalError {
}
#[track_caller]
fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
fn check_fail(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
error: impl FnOnce(ConstEvalError) -> bool,
) {
let (db, file_id) = TestDB::with_single_file(ra_fixture);
match eval_goal(&db, file_id) {
Ok(_) => panic!("Expected fail, but it succeeded"),
@ -42,7 +45,7 @@ fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
}
#[track_caller]
fn check_number(ra_fixture: &str, answer: i128) {
fn check_number(#[rust_analyzer::rust_fixture] ra_fixture: &str, answer: i128) {
check_answer(ra_fixture, |b, _| {
assert_eq!(
b,
@ -54,7 +57,7 @@ fn check_number(ra_fixture: &str, answer: i128) {
}
#[track_caller]
fn check_str(ra_fixture: &str, answer: &str) {
fn check_str(#[rust_analyzer::rust_fixture] ra_fixture: &str, answer: &str) {
check_answer(ra_fixture, |b, mm| {
let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
let size = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
@ -71,7 +74,10 @@ fn check_str(ra_fixture: &str, answer: &str) {
}
#[track_caller]
fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
fn check_answer(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
check: impl FnOnce(&[u8], &MemoryMap),
) {
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
let file_id = *file_ids.last().unwrap();
let r = match eval_goal(&db, file_id) {

View file

@ -26,7 +26,7 @@ enum DynCompatibilityViolationKind {
}
fn check_dyn_compatibility<'a>(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expected: impl IntoIterator<Item = (&'a str, Vec<DynCompatibilityViolationKind>)>,
) {
let mut expected: FxHashMap<_, _> =

View file

@ -25,7 +25,10 @@ fn current_machine_data_layout() -> String {
.unwrap()
}
fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutError> {
fn eval_goal(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
minicore: &str,
) -> Result<Arc<Layout>, LayoutError> {
let target_data_layout = current_machine_data_layout();
let ra_fixture = format!(
"//- target_data_layout: {target_data_layout}\n{minicore}//- /main.rs crate:test\n{ra_fixture}",
@ -81,7 +84,10 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
}
/// A version of `eval_goal` for types that can not be expressed in ADTs, like closures and `impl Trait`
fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutError> {
fn eval_expr(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
minicore: &str,
) -> Result<Arc<Layout>, LayoutError> {
let target_data_layout = current_machine_data_layout();
let ra_fixture = format!(
"//- target_data_layout: {target_data_layout}\n{minicore}//- /main.rs crate:test\nfn main(){{let goal = {{{ra_fixture}}};}}",
@ -114,21 +120,31 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
}
#[track_caller]
fn check_size_and_align(ra_fixture: &str, minicore: &str, size: u64, align: u64) {
fn check_size_and_align(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
minicore: &str,
size: u64,
align: u64,
) {
let l = eval_goal(ra_fixture, minicore).unwrap();
assert_eq!(l.size.bytes(), size, "size mismatch");
assert_eq!(l.align.abi.bytes(), align, "align mismatch");
}
#[track_caller]
fn check_size_and_align_expr(ra_fixture: &str, minicore: &str, size: u64, align: u64) {
fn check_size_and_align_expr(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
minicore: &str,
size: u64,
align: u64,
) {
let l = eval_expr(ra_fixture, minicore).unwrap();
assert_eq!(l.size.bytes(), size, "size mismatch");
assert_eq!(l.align.abi.bytes(), align, "align mismatch");
}
#[track_caller]
fn check_fail(ra_fixture: &str, e: LayoutError) {
fn check_fail(#[rust_analyzer::rust_fixture] ra_fixture: &str, e: LayoutError) {
let r = eval_goal(ra_fixture, "");
assert_eq!(r, Err(e));
}

View file

@ -37,11 +37,15 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String),
Ok((output.stdout().into_owned(), output.stderr().into_owned()))
}
fn check_pass(ra_fixture: &str) {
fn check_pass(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_pass_and_stdio(ra_fixture, "", "");
}
fn check_pass_and_stdio(ra_fixture: &str, expected_stdout: &str, expected_stderr: &str) {
fn check_pass_and_stdio(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expected_stdout: &str,
expected_stderr: &str,
) {
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
let file_id = *file_ids.last().unwrap();
let x = eval_main(&db, file_id);
@ -73,7 +77,7 @@ fn check_pass_and_stdio(ra_fixture: &str, expected_stdout: &str, expected_stderr
}
}
fn check_panic(ra_fixture: &str, expected_panic: &str) {
fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic: &str) {
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
let file_id = *file_ids.last().unwrap();
let e = eval_main(&db, file_id).unwrap_err();

View file

@ -69,27 +69,32 @@ fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> {
}
#[track_caller]
fn check_types(ra_fixture: &str) {
fn check_types(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_impl(ra_fixture, false, true, false)
}
#[track_caller]
fn check_types_source_code(ra_fixture: &str) {
fn check_types_source_code(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_impl(ra_fixture, false, true, true)
}
#[track_caller]
fn check_no_mismatches(ra_fixture: &str) {
fn check_no_mismatches(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_impl(ra_fixture, true, false, false)
}
#[track_caller]
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_impl(ra_fixture, false, false, false)
}
#[track_caller]
fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_source: bool) {
fn check_impl(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
allow_none: bool,
only_types: bool,
display_source: bool,
) {
let _tracing = setup_tracing();
let (db, files) = TestDB::with_many_files(ra_fixture);
@ -282,7 +287,7 @@ fn pat_node(
})
}
fn infer(ra_fixture: &str) -> String {
fn infer(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
infer_with_mismatches(ra_fixture, false)
}
@ -520,13 +525,13 @@ fn ellipsize(mut text: String, max_len: usize) -> String {
text
}
fn check_infer(ra_fixture: &str, expect: Expect) {
fn check_infer(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let mut actual = infer(ra_fixture);
actual.push('\n');
expect.assert_eq(&actual);
}
fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
fn check_infer_with_mismatches(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let mut actual = infer_with_mismatches(ra_fixture, true);
actual.push('\n');
expect.assert_eq(&actual);

View file

@ -14,7 +14,7 @@ use crate::test_db::TestDB;
use super::visit_module;
fn check_closure_captures(ra_fixture: &str, expect: Expect) {
fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, file_id) = TestDB::with_single_file(ra_fixture);
let module = db.module_for_file(file_id);
let def_map = module.def_map(&db);

View file

@ -968,7 +968,7 @@ struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V);
}
#[track_caller]
fn check(ra_fixture: &str, expected: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: Expect) {
// use tracing_subscriber::{layer::SubscriberExt, Layer};
// let my_layer = tracing_subscriber::fmt::layer();
// let _g = tracing::subscriber::set_default(tracing_subscriber::registry().with(

View file

@ -933,7 +933,7 @@ mod tests_setter {
use super::*;
fn check_not_applicable(ra_fixture: &str) {
fn check_not_applicable(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_assist_not_applicable(generate_setter, ra_fixture)
}

View file

@ -130,22 +130,36 @@ pub(crate) fn check_assist_by_label(
// `extract_ranges` and mark the target as `<target> </target>` in the
// fixture?
#[track_caller]
pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) {
pub(crate) fn check_assist_target(
assist: Handler,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
target: &str,
) {
check(assist, ra_fixture, ExpectedResult::Target(target), None);
}
#[track_caller]
pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) {
pub(crate) fn check_assist_not_applicable(
assist: Handler,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
check(assist, ra_fixture, ExpectedResult::NotApplicable, None);
}
#[track_caller]
pub(crate) fn check_assist_not_applicable_by_label(assist: Handler, ra_fixture: &str, label: &str) {
pub(crate) fn check_assist_not_applicable_by_label(
assist: Handler,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
label: &str,
) {
check(assist, ra_fixture, ExpectedResult::NotApplicable, Some(label));
}
#[track_caller]
pub(crate) fn check_assist_not_applicable_for_import_one(assist: Handler, ra_fixture: &str) {
pub(crate) fn check_assist_not_applicable_for_import_one(
assist: Handler,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
check_with_config(
TEST_CONFIG_IMPORT_ONE,
assist,
@ -157,7 +171,10 @@ pub(crate) fn check_assist_not_applicable_for_import_one(assist: Handler, ra_fix
/// Check assist in unresolved state. Useful to check assists for lazy computation.
#[track_caller]
pub(crate) fn check_assist_unresolved(assist: Handler, ra_fixture: &str) {
pub(crate) fn check_assist_unresolved(
assist: Handler,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
check(assist, ra_fixture, ExpectedResult::Unresolved, None);
}

View file

@ -6,7 +6,7 @@ use crate::{
tests::{position, TEST_CONFIG},
};
fn check_expected_type_and_name(ra_fixture: &str, expect: Expect) {
fn check_expected_type_and_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, pos) = position(ra_fixture);
let config = TEST_CONFIG;
let (completion_context, _analysis) = CompletionContext::new(&db, pos, &config).unwrap();

View file

@ -693,20 +693,28 @@ mod tests {
};
#[track_caller]
fn check(ra_fixture: &str, kind: impl Into<CompletionItemKind>, expect: Expect) {
fn check(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
kind: impl Into<CompletionItemKind>,
expect: Expect,
) {
let actual = do_completion(ra_fixture, kind.into());
expect.assert_debug_eq(&actual);
}
#[track_caller]
fn check_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
fn check_kinds(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
kinds: &[CompletionItemKind],
expect: Expect,
) {
let actual: Vec<_> =
kinds.iter().flat_map(|&kind| do_completion(ra_fixture, kind)).collect();
expect.assert_debug_eq(&actual);
}
#[track_caller]
fn check_function_relevance(ra_fixture: &str, expect: Expect) {
fn check_function_relevance(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let actual: Vec<_> =
do_completion(ra_fixture, CompletionItemKind::SymbolKind(SymbolKind::Method))
.into_iter()
@ -717,7 +725,11 @@ mod tests {
}
#[track_caller]
fn check_relevance_for_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
fn check_relevance_for_kinds(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
kinds: &[CompletionItemKind],
expect: Expect,
) {
let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
actual.retain(|it| kinds.contains(&it.kind));
actual.sort_by_key(|it| cmp::Reverse(it.relevance.score()));
@ -725,7 +737,7 @@ mod tests {
}
#[track_caller]
fn check_relevance(ra_fixture: &str, expect: Expect) {
fn check_relevance(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
actual.retain(|it| it.kind != CompletionItemKind::Snippet);
actual.retain(|it| it.kind != CompletionItemKind::Keyword);

View file

@ -89,22 +89,24 @@ pub(crate) const TEST_CONFIG: CompletionConfig<'_> = CompletionConfig {
exclude_traits: &[],
};
pub(crate) fn completion_list(ra_fixture: &str) -> String {
pub(crate) fn completion_list(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
completion_list_with_config(TEST_CONFIG, ra_fixture, true, None)
}
pub(crate) fn completion_list_no_kw(ra_fixture: &str) -> String {
pub(crate) fn completion_list_no_kw(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
completion_list_with_config(TEST_CONFIG, ra_fixture, false, None)
}
pub(crate) fn completion_list_no_kw_with_private_editable(ra_fixture: &str) -> String {
pub(crate) fn completion_list_no_kw_with_private_editable(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> String {
let mut config = TEST_CONFIG;
config.enable_private_editable = true;
completion_list_with_config(config, ra_fixture, false, None)
}
pub(crate) fn completion_list_with_trigger_character(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
trigger_character: Option<char>,
) -> String {
completion_list_with_config(TEST_CONFIG, ra_fixture, true, trigger_character)
@ -112,7 +114,7 @@ pub(crate) fn completion_list_with_trigger_character(
fn completion_list_with_config_raw(
config: CompletionConfig<'_>,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
include_keywords: bool,
trigger_character: Option<char>,
) -> Vec<CompletionItem> {
@ -135,7 +137,7 @@ fn completion_list_with_config_raw(
fn completion_list_with_config(
config: CompletionConfig<'_>,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
include_keywords: bool,
trigger_character: Option<char>,
) -> String {
@ -148,7 +150,9 @@ fn completion_list_with_config(
}
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
pub(crate) fn position(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (RootDatabase, FilePosition) {
let change_fixture = ChangeFixture::parse(ra_fixture);
let mut database = RootDatabase::default();
database.enable_proc_attr_macros();
@ -253,27 +257,33 @@ pub(crate) fn check_edit_with_config(
assert_eq_text!(&ra_fixture_after, &actual)
}
pub(crate) fn check(ra_fixture: &str, expect: Expect) {
pub(crate) fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture);
expect.assert_eq(&actual);
}
pub(crate) fn check_with_base_items(ra_fixture: &str, expect: Expect) {
pub(crate) fn check_with_base_items(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
check(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"), expect)
}
pub(crate) fn check_no_kw(ra_fixture: &str, expect: Expect) {
pub(crate) fn check_no_kw(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let actual = completion_list_no_kw(ra_fixture);
expect.assert_eq(&actual)
}
pub(crate) fn check_with_private_editable(ra_fixture: &str, expect: Expect) {
pub(crate) fn check_with_private_editable(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let actual = completion_list_no_kw_with_private_editable(ra_fixture);
expect.assert_eq(&actual);
}
pub(crate) fn check_with_trigger_character(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
trigger_character: Option<char>,
expect: Expect,
) {

View file

@ -10,7 +10,11 @@ use crate::{
CompletionConfig,
};
fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Expect) {
fn check_with_config(
config: CompletionConfig<'_>,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let actual = completion_list_with_config(
config,
&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"),

View file

@ -6,11 +6,15 @@ use crate::{
CompletionConfig,
};
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
check_with_config(TEST_CONFIG, ra_fixture, expect);
}
fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Expect) {
fn check_with_config(
config: CompletionConfig<'_>,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (db, position) = crate::tests::position(ra_fixture);
let (ctx, analysis) = crate::context::CompletionContext::new(&db, position, &config).unwrap();

View file

@ -4,7 +4,7 @@ use itertools::Itertools;
use crate::tests::{completion_list_with_config_raw, position, TEST_CONFIG};
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let completions = completion_list_with_config_raw(TEST_CONFIG, ra_fixture, true, None);
let (db, position) = position(ra_fixture);
let mut actual = db.file_text(position.file_id).to_string();

View file

@ -4,7 +4,7 @@ use either::Either;
use hir::{InFile, Semantics, Type};
use parser::T;
use syntax::{
ast::{self, HasArgList, HasName},
ast::{self, AstChildren, HasArgList, HasAttrs, HasName},
match_ast, AstNode, NodeOrToken, SyntaxToken,
};
@ -37,6 +37,10 @@ impl ActiveParameter {
_ => None,
})
}
pub fn attrs(&self) -> Option<AstChildren<ast::Attr>> {
self.src.as_ref().and_then(|param| Some(param.value.as_ref().right()?.attrs()))
}
}
/// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable.

View file

@ -1330,7 +1330,7 @@ fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior
assert_eq!(result.map(|u| u.to_string()), None);
}
fn check_guess(ra_fixture: &str, expected: ImportGranularityGuess) {
fn check_guess(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: ImportGranularityGuess) {
let syntax = ast::SourceFile::parse(ra_fixture, span::Edition::CURRENT).tree().syntax().clone();
let file = ImportScope::from(syntax).unwrap();
assert_eq!(super::guess_granularity_from_scope(&file), expected);

View file

@ -421,7 +421,7 @@ mod tests {
use super::*;
#[track_caller]
fn check(ra_fixture: &str, expected: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &str) {
let (db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
let frange = FileRange { file_id, range: range_or_offset.into() };

View file

@ -123,7 +123,9 @@ mod tests {
use crate::RootDatabase;
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
pub(crate) fn position(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (RootDatabase, FilePosition) {
let change_fixture = ChangeFixture::parse(ra_fixture);
let mut database = RootDatabase::default();
database.apply_change(change_fixture.change);
@ -133,7 +135,7 @@ mod tests {
(database, FilePosition { file_id, offset })
}
fn check_trait(ra_fixture: &str, expect: Expect) {
fn check_trait(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, position) = position(ra_fixture);
let sema = Semantics::new(&db);
let file = sema.parse(position.file_id);
@ -147,7 +149,7 @@ mod tests {
expect.assert_eq(&actual);
}
fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
fn check_missing_assoc(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (db, position) = position(ra_fixture);
let sema = Semantics::new(&db);
let file = sema.parse(position.file_id);

View file

@ -41,7 +41,7 @@ pub(crate) fn inactive_code(
mod tests {
use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};
pub(crate) fn check(ra_fixture: &str) {
pub(crate) fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let config = DiagnosticsConfig {
disabled: std::iter::once("unlinked-file".to_owned()).collect(),
..DiagnosticsConfig::test_sample()

View file

@ -26,7 +26,7 @@ mod tests {
use test_utils::skip_slow_tests;
#[track_caller]
fn check_diagnostics_no_bails(ra_fixture: &str) {
fn check_diagnostics_no_bails(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
cov_mark::check_count!(validate_match_bailed_out, 0);
crate::tests::check_diagnostics(ra_fixture)
}

View file

@ -61,7 +61,7 @@ mod tests {
};
#[track_caller]
pub(crate) fn check_diagnostics(ra_fixture: &str) {
pub(crate) fn check_diagnostics(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let mut config = DiagnosticsConfig::test_sample();
config.disabled.insert("inactive-code".to_owned());
config.disabled.insert("E0599".to_owned());

View file

@ -191,7 +191,7 @@ pub(crate) fn check_has_single_fix(ra_fixture_before: &str, ra_fixture_after: &s
}
/// Checks that there's a diagnostic *without* fix at `$0`.
pub(crate) fn check_no_fix(ra_fixture: &str) {
pub(crate) fn check_no_fix(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (db, file_position) = RootDatabase::with_position(ra_fixture);
let diagnostic = super::full_diagnostics(
&db,
@ -205,21 +205,27 @@ pub(crate) fn check_no_fix(ra_fixture: &str) {
}
#[track_caller]
pub(crate) fn check_diagnostics(ra_fixture: &str) {
pub(crate) fn check_diagnostics(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let mut config = DiagnosticsConfig::test_sample();
config.disabled.insert("inactive-code".to_owned());
check_diagnostics_with_config(config, ra_fixture)
}
#[track_caller]
pub(crate) fn check_diagnostics_with_disabled(ra_fixture: &str, disabled: &[&str]) {
pub(crate) fn check_diagnostics_with_disabled(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
disabled: &[&str],
) {
let mut config = DiagnosticsConfig::test_sample();
config.disabled.extend(disabled.iter().map(|&s| s.to_owned()));
check_diagnostics_with_config(config, ra_fixture)
}
#[track_caller]
pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixture: &str) {
pub(crate) fn check_diagnostics_with_config(
config: DiagnosticsConfig,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
let (db, files) = RootDatabase::with_many_files(ra_fixture);
let mut annotations = files
.iter()

View file

@ -220,7 +220,11 @@ mod tests {
location: AnnotationLocation::AboveName,
};
fn check_with_config(ra_fixture: &str, expect: Expect, config: &AnnotationConfig) {
fn check_with_config(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
config: &AnnotationConfig,
) {
let (analysis, file_id) = fixture::file(ra_fixture);
let annotations: Vec<Annotation> = analysis
@ -233,7 +237,7 @@ mod tests {
expect.assert_debug_eq(&annotations);
}
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
check_with_config(ra_fixture, expect, &DEFAULT_CONFIG);
}

View file

@ -173,7 +173,7 @@ mod tests {
fn check_hierarchy(
exclude_tests: bool,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expected_nav: Expect,
expected_incoming: Expect,
expected_outgoing: Expect,

View file

@ -16,7 +16,7 @@ use crate::{
};
fn check_external_docs(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
target_dir: Option<&str>,
expect_web_url: Option<Expect>,
expect_local_url: Option<Expect>,
@ -41,7 +41,7 @@ fn check_external_docs(
}
}
fn check_rewrite(ra_fixture: &str, expect: Expect) {
fn check_rewrite(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let sema = &Semantics::new(&*analysis.db);
let (cursor_def, docs) = def_under_cursor(sema, &position);
@ -49,7 +49,7 @@ fn check_rewrite(ra_fixture: &str, expect: Expect) {
expect.assert_eq(&res)
}
fn check_doc_links(ra_fixture: &str) {
fn check_doc_links(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let key_fn = |&(FileRange { file_id, range }, _): &_| (file_id, range.start());
let (analysis, position, mut expected) = fixture::annotations(ra_fixture);

View file

@ -296,7 +296,7 @@ mod tests {
use crate::fixture;
#[track_caller]
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, pos) = fixture::position(ra_fixture);
let expansion = analysis.expand_macro(pos).unwrap().unwrap();
let actual = format!("{}\n{}", expansion.name, expansion.expansion);

View file

@ -257,7 +257,7 @@ mod tests {
use super::*;
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let file = SourceFile::parse(ra_fixture, span::Edition::CURRENT).ok().unwrap();
let structure = file_structure(&file);
expect.assert_debug_eq(&structure)

View file

@ -5,7 +5,7 @@ use test_utils::{extract_annotations, RangeOrOffset};
use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};
/// Creates analysis for a single file.
pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) {
pub(crate) fn file(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Analysis, FileId) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();
@ -14,7 +14,9 @@ pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) {
}
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) {
pub(crate) fn position(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Analysis, FilePosition) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();
@ -25,7 +27,7 @@ pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) {
}
/// Creates analysis for a single file, returns range marked with a pair of $0.
pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) {
pub(crate) fn range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Analysis, FileRange) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();
@ -36,7 +38,9 @@ pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) {
}
/// Creates analysis for a single file, returns range marked with a pair of $0 or a position marked with $0.
pub(crate) fn range_or_position(ra_fixture: &str) -> (Analysis, FileId, RangeOrOffset) {
pub(crate) fn range_or_position(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Analysis, FileId, RangeOrOffset) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();
@ -46,7 +50,9 @@ pub(crate) fn range_or_position(ra_fixture: &str) -> (Analysis, FileId, RangeOrO
}
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) {
pub(crate) fn annotations(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Analysis, FilePosition, Vec<(FileRange, String)>) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();
@ -69,7 +75,9 @@ pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(Fil
}
/// Creates analysis from a multi-file fixture with annotations without $0
pub(crate) fn annotations_without_marker(ra_fixture: &str) -> (Analysis, Vec<(FileRange, String)>) {
pub(crate) fn annotations_without_marker(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Analysis, Vec<(FileRange, String)>) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.db.enable_proc_attr_macros();

View file

@ -286,7 +286,7 @@ mod tests {
use super::*;
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (ranges, text) = extract_tags(ra_fixture, "fold");
let parse = SourceFile::parse(&text, span::Edition::CURRENT);

View file

@ -83,7 +83,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis
.goto_declaration(position)

View file

@ -424,7 +424,7 @@ mod tests {
use syntax::SmolStr;
#[track_caller]
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
@ -443,14 +443,14 @@ mod tests {
assert_eq!(expected, navs);
}
fn check_unresolved(ra_fixture: &str) {
fn check_unresolved(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position) = fixture::position(ra_fixture);
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {navs:?}")
}
fn check_name(expected_name: &str, ra_fixture: &str) {
fn check_name(expected_name: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, _) = fixture::annotations(ra_fixture);
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
assert!(navs.len() < 2, "expected single navigation target but encountered {}", navs.len());

View file

@ -129,7 +129,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.goto_implementation(position).unwrap().unwrap().info;

View file

@ -118,7 +118,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.goto_type_definition(position).unwrap().unwrap().info;
assert!(!navs.is_empty(), "navigation is empty");

View file

@ -684,12 +684,15 @@ mod tests {
};
#[track_caller]
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(ra_fixture, ENABLED_CONFIG);
}
#[track_caller]
fn check_with_config(ra_fixture: &str, config: HighlightRelatedConfig) {
fn check_with_config(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
config: HighlightRelatedConfig,
) {
let (analysis, pos, annotations) = fixture::annotations(ra_fixture);
let hls = analysis.highlight_related(config, pos).unwrap().unwrap_or_default();

View file

@ -23,7 +23,7 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig {
max_subst_ty_len: super::SubstTyLen::Unlimited,
};
fn check_hover_no_result(ra_fixture: &str) {
fn check_hover_no_result(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -35,7 +35,7 @@ fn check_hover_no_result(ra_fixture: &str) {
}
#[track_caller]
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -55,7 +55,7 @@ fn check(ra_fixture: &str, expect: Expect) {
#[track_caller]
fn check_hover_fields_limit(
fields_count: impl Into<Option<usize>>,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, position) = fixture::position(ra_fixture);
@ -81,7 +81,7 @@ fn check_hover_fields_limit(
#[track_caller]
fn check_hover_enum_variants_limit(
variants_count: impl Into<Option<usize>>,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, position) = fixture::position(ra_fixture);
@ -105,7 +105,11 @@ fn check_hover_enum_variants_limit(
}
#[track_caller]
fn check_assoc_count(count: usize, ra_fixture: &str, expect: Expect) {
fn check_assoc_count(
count: usize,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -126,7 +130,7 @@ fn check_assoc_count(count: usize, ra_fixture: &str, expect: Expect) {
expect.assert_eq(&actual)
}
fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
fn check_hover_no_links(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -143,7 +147,7 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
expect.assert_eq(&actual)
}
fn check_hover_no_memory_layout(ra_fixture: &str, expect: Expect) {
fn check_hover_no_memory_layout(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -160,7 +164,7 @@ fn check_hover_no_memory_layout(ra_fixture: &str, expect: Expect) {
expect.assert_eq(&actual)
}
fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
fn check_hover_no_markdown(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
@ -181,7 +185,7 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
expect.assert_eq(&actual)
}
fn check_actions(ra_fixture: &str, expect: Expect) {
fn check_actions(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
let mut hover = analysis
.hover(
@ -206,13 +210,13 @@ fn check_actions(ra_fixture: &str, expect: Expect) {
expect.assert_debug_eq(&hover.info.actions)
}
fn check_hover_range(ra_fixture: &str, expect: Expect) {
fn check_hover_range(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis.hover(&HOVER_BASE_CONFIG, range).unwrap().unwrap();
expect.assert_eq(hover.info.markup.as_str())
}
fn check_hover_range_actions(ra_fixture: &str, expect: Expect) {
fn check_hover_range_actions(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, range) = fixture::range(ra_fixture);
let mut hover = analysis
.hover(&HoverConfig { links_in_hover: true, ..HOVER_BASE_CONFIG }, range)
@ -234,7 +238,7 @@ fn check_hover_range_actions(ra_fixture: &str, expect: Expect) {
expect.assert_debug_eq(&hover.info.actions);
}
fn check_hover_range_no_results(ra_fixture: &str) {
fn check_hover_range_no_results(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis.hover(&HOVER_BASE_CONFIG, range).unwrap();
assert!(hover.is_none());

View file

@ -798,12 +798,15 @@ mod tests {
};
#[track_caller]
pub(super) fn check(ra_fixture: &str) {
pub(super) fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(TEST_CONFIG, ra_fixture);
}
#[track_caller]
pub(super) fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) {
pub(super) fn check_with_config(
config: InlayHintsConfig,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
let (analysis, file_id) = fixture::file(ra_fixture);
let mut expected = extract_annotations(&analysis.file_text(file_id).unwrap());
let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
@ -819,7 +822,11 @@ mod tests {
}
#[track_caller]
pub(super) fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) {
pub(super) fn check_expect(
config: InlayHintsConfig,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, file_id) = fixture::file(ra_fixture);
let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
let filtered =
@ -830,7 +837,11 @@ mod tests {
/// Computes inlay hints for the fixture, applies all the provided text edits and then runs
/// expect test.
#[track_caller]
pub(super) fn check_edit(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) {
pub(super) fn check_edit(
config: InlayHintsConfig,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, file_id) = fixture::file(ra_fixture);
let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
@ -849,7 +860,10 @@ mod tests {
}
#[track_caller]
pub(super) fn check_no_edit(config: InlayHintsConfig, ra_fixture: &str) {
pub(super) fn check_no_edit(
config: InlayHintsConfig,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
let (analysis, file_id) = fixture::file(ra_fixture);
let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();

View file

@ -185,7 +185,7 @@ mod tests {
};
#[track_caller]
fn check_types(ra_fixture: &str) {
fn check_types(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, ra_fixture);
}

View file

@ -83,7 +83,7 @@ mod tests {
use crate::inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG};
#[track_caller]
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(InlayHintsConfig { sized_bound: true, ..DISABLED_CONFIG }, ra_fixture);
}

View file

@ -86,14 +86,14 @@ mod tests {
};
#[track_caller]
fn check_chains(ra_fixture: &str) {
fn check_chains(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, ra_fixture);
}
#[track_caller]
pub(super) fn check_expect_clear_loc(
config: InlayHintsConfig,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, file_id) = fixture::file(ra_fixture);

View file

@ -105,7 +105,7 @@ mod tests {
};
#[track_caller]
fn check_discriminants(ra_fixture: &str) {
fn check_discriminants(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(
InlayHintsConfig { discriminant_hints: DiscriminantHints::Always, ..DISABLED_CONFIG },
ra_fixture,
@ -113,7 +113,7 @@ mod tests {
}
#[track_caller]
fn check_discriminants_fieldless(ra_fixture: &str) {
fn check_discriminants_fieldless(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(
InlayHintsConfig {
discriminant_hints: DiscriminantHints::Fieldless,

View file

@ -142,7 +142,7 @@ mod tests {
};
#[track_caller]
fn generic_param_name_hints_always(ra_fixture: &str) {
fn generic_param_name_hints_always(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(
InlayHintsConfig {
generic_parameter_hints: GenericParameterHints {
@ -157,7 +157,7 @@ mod tests {
}
#[track_caller]
fn generic_param_name_hints_const_only(ra_fixture: &str) {
fn generic_param_name_hints_const_only(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(
InlayHintsConfig {
generic_parameter_hints: GenericParameterHints {

View file

@ -269,7 +269,7 @@ mod tests {
};
#[track_caller]
fn check_params(ra_fixture: &str) {
fn check_params(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
check_with_config(
InlayHintsConfig { parameter_hints: true, ..DISABLED_CONFIG },
ra_fixture,

View file

@ -405,7 +405,7 @@ mod tests {
#[allow(dead_code)]
#[track_caller]
fn no_moniker(ra_fixture: &str) {
fn no_moniker(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position) = fixture::position(ra_fixture);
if let Some(x) = analysis.moniker(position).unwrap() {
assert_eq!(x.info.len(), 0, "Moniker found but no moniker expected: {x:?}");
@ -413,7 +413,12 @@ mod tests {
}
#[track_caller]
fn check_local_moniker(ra_fixture: &str, identifier: &str, package: &str, kind: MonikerKind) {
fn check_local_moniker(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
identifier: &str,
package: &str,
kind: MonikerKind,
) {
let (analysis, position) = fixture::position(ra_fixture);
let x = analysis.moniker(position).unwrap().expect("no moniker found").info;
assert_eq!(x.len(), 1);
@ -433,7 +438,12 @@ mod tests {
}
#[track_caller]
fn check_moniker(ra_fixture: &str, identifier: &str, package: &str, kind: MonikerKind) {
fn check_moniker(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
identifier: &str,
package: &str,
kind: MonikerKind,
) {
let (analysis, position) = fixture::position(ra_fixture);
let x = analysis.moniker(position).unwrap().expect("no moniker found").info;
assert_eq!(x.len(), 1);

View file

@ -180,7 +180,11 @@ mod tests {
use crate::Direction;
fn check(ra_fixture: &str, expect: Expect, direction: Direction) {
fn check(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
direction: Direction,
) {
let (analysis, range) = fixture::range(ra_fixture);
let edit = analysis.move_item(range, direction).unwrap().unwrap_or_default();
let mut file = analysis.file_text(range.file_id).unwrap().to_string();

View file

@ -70,7 +70,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.parent_module(position).unwrap();
let navs = navs

View file

@ -1255,11 +1255,15 @@ impl Foo {
);
}
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
check_with_scope(ra_fixture, None, expect)
}
fn check_with_scope(ra_fixture: &str, search_scope: Option<SearchScope>, expect: Expect) {
fn check_with_scope(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
search_scope: Option<SearchScope>,
expect: Expect,
) {
let (analysis, pos) = fixture::position(ra_fixture);
let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap();

View file

@ -494,14 +494,22 @@ mod tests {
};
}
fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) {
fn check_expect(
new_name: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, position) = fixture::position(ra_fixture);
let source_change =
analysis.rename(position, new_name).unwrap().expect("Expect returned a RenameError");
expect.assert_eq(&filter_expect(source_change))
}
fn check_expect_will_rename_file(new_name: &str, ra_fixture: &str, expect: Expect) {
fn check_expect_will_rename_file(
new_name: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
) {
let (analysis, position) = fixture::position(ra_fixture);
let source_change = analysis
.will_rename_file(position.file_id, new_name)
@ -510,7 +518,7 @@ mod tests {
expect.assert_eq(&filter_expect(source_change))
}
fn check_prepare(ra_fixture: &str, expect: Expect) {
fn check_prepare(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let result = analysis
.prepare_rename(position)

View file

@ -748,7 +748,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let result = analysis
.runnables(position.file_id)
@ -769,7 +769,7 @@ mod tests {
expect.assert_debug_eq(&result);
}
fn check_tests(ra_fixture: &str, expect: Expect) {
fn check_tests(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let tests = analysis.related_tests(position, None).unwrap();
let navigation_targets = tests.into_iter().map(|runnable| runnable.nav).collect::<Vec<_>>();

View file

@ -692,7 +692,9 @@ mod tests {
use crate::RootDatabase;
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
pub(crate) fn position(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (RootDatabase, FilePosition) {
let change_fixture = ChangeFixture::parse(ra_fixture);
let mut database = RootDatabase::default();
database.apply_change(change_fixture.change);
@ -703,7 +705,7 @@ mod tests {
}
#[track_caller]
fn check(ra_fixture: &str, expect: Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let fixture = format!(
r#"
//- minicore: sized, fn

View file

@ -67,7 +67,10 @@ mod tests {
use super::ssr_assists;
fn get_assists(ra_fixture: &str, resolve: AssistResolveStrategy) -> Vec<Assist> {
fn get_assists(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
resolve: AssistResolveStrategy,
) -> Vec<Assist> {
let (mut db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
let mut local_roots = FxHashSet::default();
local_roots.insert(test_fixture::WORKSPACE);

View file

@ -291,7 +291,10 @@ mod tests {
use super::VendoredLibrariesConfig;
fn check_all_ranges(ra_fixture: &str, vendored_libs_config: VendoredLibrariesConfig<'_>) {
fn check_all_ranges(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
vendored_libs_config: VendoredLibrariesConfig<'_>,
) {
let (analysis, ranges) = fixture::annotations_without_marker(ra_fixture);
let s = StaticIndex::compute(&analysis, vendored_libs_config);
let mut range_set: FxHashSet<_> = ranges.iter().map(|it| it.0).collect();
@ -310,7 +313,10 @@ mod tests {
}
#[track_caller]
fn check_definitions(ra_fixture: &str, vendored_libs_config: VendoredLibrariesConfig<'_>) {
fn check_definitions(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
vendored_libs_config: VendoredLibrariesConfig<'_>,
) {
let (analysis, ranges) = fixture::annotations_without_marker(ra_fixture);
let s = StaticIndex::compute(&analysis, vendored_libs_config);
let mut range_set: FxHashSet<_> = ranges.iter().map(|it| it.0).collect();

View file

@ -28,7 +28,14 @@ pub(super) fn ra_fixture(
expanded: &ast::String,
) -> Option<()> {
let active_parameter = ActiveParameter::at_token(sema, expanded.syntax().clone())?;
if !active_parameter.ident().is_some_and(|name| name.text().starts_with("ra_fixture")) {
let has_rust_fixture_attr = active_parameter.attrs().is_some_and(|attrs| {
attrs.filter_map(|attr| attr.as_simple_path()).any(|path| {
path.segments()
.zip(["rust_analyzer", "rust_fixture"])
.all(|(seg, name)| seg.name_ref().map_or(false, |nr| nr.text() == name))
})
});
if !has_rust_fixture_attr {
return None;
}
let value = literal.value().ok()?;

View file

@ -45,7 +45,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="punctuation">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="tool_module attribute">rust_analyzer</span><span class="operator attribute">::</span><span class="tool_module attribute">rust_fixture</span><span class="attribute_bracket attribute">]</span> <span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="punctuation">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span><span class="none injected">

View file

@ -990,7 +990,7 @@ impl t for foo {
fn test_injection() {
check_highlighting(
r##"
fn fixture(ra_fixture: &str) {}
fn fixture(#[rust_analyzer::rust_fixture] ra_fixture: &str) {}
fn main() {
fixture(r#"
@ -1188,7 +1188,11 @@ fn foo(x: &fn(&dyn Trait)) {}
/// Highlights the code given by the `ra_fixture` argument, renders the
/// result as HTML, and compares it with the HTML file given as `snapshot`.
/// Note that the `snapshot` file is overwritten by the rendered HTML.
fn check_highlighting(ra_fixture: &str, expect: ExpectFile, rainbow: bool) {
fn check_highlighting(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: ExpectFile,
rainbow: bool,
) {
let (analysis, file_id) = fixture::file(ra_fixture.trim());
let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap();
expect.assert_eq(actual_html)

View file

@ -889,7 +889,7 @@ fn main() {
type_char_noop(
'{',
r##"
fn check_with(ra_fixture: &str, expect: Expect) {
fn check_with(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let base = r#"
enum E { T(), R$0, C }
use self::E::X;
@ -1191,7 +1191,7 @@ fn f(n: a<>b::<d>::c) {}
type_char_noop(
'(',
r##"
fn check_with(ra_fixture: &str, expect: Expect) {
fn check_with(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let base = r#"
enum E { T(), R$0, C }
use self::E::X;

View file

@ -220,7 +220,9 @@ mod tests {
use crate::fixture;
use expect_test::expect;
fn make_memory_layout(ra_fixture: &str) -> Option<RecursiveMemoryLayout> {
fn make_memory_layout(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> Option<RecursiveMemoryLayout> {
let (analysis, position, _) = fixture::annotations(ra_fixture);
view_memory_layout(&analysis.db, position)

View file

@ -148,7 +148,7 @@ mod tests {
use crate::fixture;
fn check(ra_fixture: &str, expect: expect_test::Expect) {
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: expect_test::Expect) {
let (analysis, file_id) = fixture::file(ra_fixture);
let syn = analysis.view_syntax_tree(file_id).unwrap();
expect.assert_eq(&syn)

View file

@ -28,13 +28,18 @@ fn parse_string_spanned(
))
}
pub fn assert_expand(macro_name: &str, ra_fixture: &str, expect: Expect, expect_s: Expect) {
pub fn assert_expand(
macro_name: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: Expect,
expect_s: Expect,
) {
assert_expand_impl(macro_name, ra_fixture, None, expect, expect_s);
}
pub fn assert_expand_attr(
macro_name: &str,
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
attr_args: &str,
expect: Expect,
expect_s: Expect,

View file

@ -518,7 +518,7 @@ mod test {
use test_fixture::ChangeFixture;
use vfs::VfsPath;
fn position(ra_fixture: &str) -> (AnalysisHost, FilePosition) {
fn position(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (AnalysisHost, FilePosition) {
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(ra_fixture);
host.raw_database_mut().apply_change(change_fixture.change);
@ -530,7 +530,7 @@ mod test {
/// If expected == "", then assert that there are no symbols (this is basically local symbol)
#[track_caller]
fn check_symbol(ra_fixture: &str, expected: &str) {
fn check_symbol(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &str) {
let (host, position) = position(ra_fixture);
let analysis = host.analysis();

View file

@ -1993,7 +1993,7 @@ fn bar(_: usize) {}
#[track_caller]
fn check_rendered_snippets_in_source(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
edit: TextEdit,
snippets: SnippetEdit,
expect: Expect,

View file

@ -185,6 +185,14 @@ impl ast::Attr {
Some((self.simple_name()?, tt))
}
pub fn as_simple_path(&self) -> Option<ast::Path> {
let meta = self.meta()?;
if meta.eq_token().is_some() || meta.token_tree().is_some() {
return None;
}
self.path()
}
pub fn simple_name(&self) -> Option<SmolStr> {
let path = self.meta()?.path()?;
match (path.segment(), path.qualifier()) {

View file

@ -30,7 +30,9 @@ pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0);
pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static {
#[track_caller]
fn with_single_file(ra_fixture: &str) -> (Self, EditionedFileId) {
fn with_single_file(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Self, EditionedFileId) {
let fixture = ChangeFixture::parse(ra_fixture);
let mut db = Self::default();
fixture.change.apply(&mut db);
@ -39,7 +41,9 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static {
}
#[track_caller]
fn with_many_files(ra_fixture: &str) -> (Self, Vec<EditionedFileId>) {
fn with_many_files(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Self, Vec<EditionedFileId>) {
let fixture = ChangeFixture::parse(ra_fixture);
let mut db = Self::default();
fixture.change.apply(&mut db);
@ -48,7 +52,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static {
}
#[track_caller]
fn with_files(ra_fixture: &str) -> Self {
fn with_files(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self {
let fixture = ChangeFixture::parse(ra_fixture);
let mut db = Self::default();
fixture.change.apply(&mut db);
@ -58,7 +62,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static {
#[track_caller]
fn with_files_extra_proc_macros(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
proc_macros: Vec<(String, ProcMacro)>,
) -> Self {
let fixture = ChangeFixture::parse_with_proc_macros(ra_fixture, proc_macros);
@ -69,21 +73,23 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static {
}
#[track_caller]
fn with_position(ra_fixture: &str) -> (Self, FilePosition) {
fn with_position(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FilePosition) {
let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture);
let offset = range_or_offset.expect_offset();
(db, FilePosition { file_id, offset })
}
#[track_caller]
fn with_range(ra_fixture: &str) -> (Self, FileRange) {
fn with_range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FileRange) {
let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture);
let range = range_or_offset.expect_range();
(db, FileRange { file_id, range })
}
#[track_caller]
fn with_range_or_offset(ra_fixture: &str) -> (Self, EditionedFileId, RangeOrOffset) {
fn with_range_or_offset(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Self, EditionedFileId, RangeOrOffset) {
let fixture = ChangeFixture::parse(ra_fixture);
let mut db = Self::default();
fixture.change.apply(&mut db);
@ -116,12 +122,12 @@ pub struct ChangeFixture {
const SOURCE_ROOT_PREFIX: &str = "/";
impl ChangeFixture {
pub fn parse(ra_fixture: &str) -> ChangeFixture {
pub fn parse(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> ChangeFixture {
Self::parse_with_proc_macros(ra_fixture, Vec::new())
}
pub fn parse_with_proc_macros(
ra_fixture: &str,
#[rust_analyzer::rust_fixture] ra_fixture: &str,
mut proc_macro_defs: Vec<(String, ProcMacro)>,
) -> ChangeFixture {
let FixtureWithProjectMeta {

View file

@ -168,7 +168,7 @@ impl FixtureWithProjectMeta {
/// That will set toolchain to nightly and include predefined proc macros and a subset of
/// `libcore` into the fixture, see `minicore.rs` for what's available. Note that toolchain
/// defaults to stable.
pub fn parse(ra_fixture: &str) -> Self {
pub fn parse(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self {
let fixture = trim_indent(ra_fixture);
let mut fixture = fixture.as_str();
let mut toolchain = None;