Fall back to FindAllReferences if GoToDefinition have not navigated (#16512)
Follow-up of https://github.com/zed-industries/zed/pull/9243 Release Notes: - N/A --------- Co-authored-by: Alex Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
parent
f185269d03
commit
e482fcde5b
4 changed files with 237 additions and 90 deletions
|
@ -13221,6 +13221,127 @@ let foo = 15;"#,
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_goto_definition_with_find_all_references_fallback(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorLspTestContext::new_rust(
|
||||
lsp::ServerCapabilities {
|
||||
definition_provider: Some(lsp::OneOf::Left(true)),
|
||||
references_provider: Some(lsp::OneOf::Left(true)),
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
|
||||
let set_up_lsp_handlers = |empty_go_to_definition: bool, cx: &mut EditorLspTestContext| {
|
||||
let go_to_definition = cx.lsp.handle_request::<lsp::request::GotoDefinition, _, _>(
|
||||
move |params, _| async move {
|
||||
if empty_go_to_definition {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location {
|
||||
uri: params.text_document_position_params.text_document.uri,
|
||||
range: lsp::Range::new(lsp::Position::new(4, 3), lsp::Position::new(4, 6)),
|
||||
})))
|
||||
}
|
||||
},
|
||||
);
|
||||
let references =
|
||||
cx.lsp
|
||||
.handle_request::<lsp::request::References, _, _>(move |params, _| async move {
|
||||
Ok(Some(vec![lsp::Location {
|
||||
uri: params.text_document_position.text_document.uri,
|
||||
range: lsp::Range::new(lsp::Position::new(0, 8), lsp::Position::new(0, 11)),
|
||||
}]))
|
||||
});
|
||||
(go_to_definition, references)
|
||||
};
|
||||
|
||||
cx.set_state(
|
||||
&r#"fn one() {
|
||||
let mut a = ˇtwo();
|
||||
}
|
||||
|
||||
fn two() {}"#
|
||||
.unindent(),
|
||||
);
|
||||
set_up_lsp_handlers(false, &mut cx);
|
||||
let navigated = cx
|
||||
.update_editor(|editor, cx| editor.go_to_definition(&GoToDefinition, cx))
|
||||
.await
|
||||
.expect("Failed to navigate to definition");
|
||||
assert_eq!(
|
||||
navigated,
|
||||
Navigated::Yes,
|
||||
"Should have navigated to definition from the GetDefinition response"
|
||||
);
|
||||
cx.assert_editor_state(
|
||||
&r#"fn one() {
|
||||
let mut a = two();
|
||||
}
|
||||
|
||||
fn «twoˇ»() {}"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
let editors = cx.update_workspace(|workspace, cx| {
|
||||
workspace.items_of_type::<Editor>(cx).collect::<Vec<_>>()
|
||||
});
|
||||
cx.update_editor(|_, test_editor_cx| {
|
||||
assert_eq!(
|
||||
editors.len(),
|
||||
1,
|
||||
"Initially, only one, test, editor should be open in the workspace"
|
||||
);
|
||||
assert_eq!(
|
||||
test_editor_cx.view(),
|
||||
editors.last().expect("Asserted len is 1")
|
||||
);
|
||||
});
|
||||
|
||||
set_up_lsp_handlers(true, &mut cx);
|
||||
let navigated = cx
|
||||
.update_editor(|editor, cx| editor.go_to_definition(&GoToDefinition, cx))
|
||||
.await
|
||||
.expect("Failed to navigate to lookup references");
|
||||
assert_eq!(
|
||||
navigated,
|
||||
Navigated::Yes,
|
||||
"Should have navigated to references as a fallback after empty GoToDefinition response"
|
||||
);
|
||||
// We should not change the selections in the existing file,
|
||||
// if opening another milti buffer with the references
|
||||
cx.assert_editor_state(
|
||||
&r#"fn one() {
|
||||
let mut a = two();
|
||||
}
|
||||
|
||||
fn «twoˇ»() {}"#
|
||||
.unindent(),
|
||||
);
|
||||
let editors = cx.update_workspace(|workspace, cx| {
|
||||
workspace.items_of_type::<Editor>(cx).collect::<Vec<_>>()
|
||||
});
|
||||
cx.update_editor(|_, test_editor_cx| {
|
||||
assert_eq!(
|
||||
editors.len(),
|
||||
2,
|
||||
"After falling back to references search, we open a new editor with the results"
|
||||
);
|
||||
let references_fallback_text = editors
|
||||
.into_iter()
|
||||
.find(|new_editor| new_editor != test_editor_cx.view())
|
||||
.expect("Should have one non-test editor now")
|
||||
.read(test_editor_cx)
|
||||
.text(test_editor_cx);
|
||||
assert_eq!(
|
||||
references_fallback_text, "fn one() {\n let mut a = two();\n}",
|
||||
"Should use the range from the references response and not the GoToDefinition one"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||
let point = DisplayPoint::new(DisplayRow(row as u32), column as u32);
|
||||
point..point
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue