From 1412cff20fc000de314f90888149af21e7ee8290 Mon Sep 17 00:00:00 2001 From: Marek Kaput Date: Thu, 16 Jan 2025 12:57:34 +0100 Subject: [PATCH] Rewrite find references tests to insta commit-id:18955b47 --- tests/e2e/find_references/enums.rs | 71 ++++++ tests/e2e/find_references/fns.rs | 52 ++++ tests/e2e/find_references/macros.rs | 24 ++ tests/e2e/find_references/mod.rs | 151 +++++++++++ tests/e2e/find_references/structs.rs | 85 +++++++ tests/e2e/find_references/traits.rs | 238 ++++++++++++++++++ tests/e2e/find_references/vars.rs | 168 +++++++++++++ tests/e2e/main.rs | 2 +- tests/e2e/references.rs | 176 ------------- tests/e2e/support/cursor.rs | 22 +- tests/test_data/references/enum_variants.txt | 26 -- tests/test_data/references/enums.txt | 101 -------- tests/test_data/references/fns.txt | 152 ----------- tests/test_data/references/inline_macros.txt | 24 -- tests/test_data/references/methods.txt | 79 ------ tests/test_data/references/struct_members.txt | 56 ----- tests/test_data/references/structs.txt | 95 ------- tests/test_data/references/traits.txt | 69 ----- tests/test_data/references/variables.txt | 90 ------- 19 files changed, 808 insertions(+), 873 deletions(-) create mode 100644 tests/e2e/find_references/enums.rs create mode 100644 tests/e2e/find_references/fns.rs create mode 100644 tests/e2e/find_references/macros.rs create mode 100644 tests/e2e/find_references/mod.rs create mode 100644 tests/e2e/find_references/structs.rs create mode 100644 tests/e2e/find_references/traits.rs create mode 100644 tests/e2e/find_references/vars.rs delete mode 100644 tests/e2e/references.rs delete mode 100644 tests/test_data/references/enum_variants.txt delete mode 100644 tests/test_data/references/enums.txt delete mode 100644 tests/test_data/references/fns.txt delete mode 100644 tests/test_data/references/inline_macros.txt delete mode 100644 tests/test_data/references/methods.txt delete mode 100644 tests/test_data/references/struct_members.txt delete mode 100644 tests/test_data/references/structs.txt delete mode 100644 tests/test_data/references/traits.txt delete mode 100644 tests/test_data/references/variables.txt diff --git a/tests/e2e/find_references/enums.rs b/tests/e2e/find_references/enums.rs new file mode 100644 index 00000000..a791a132 --- /dev/null +++ b/tests/e2e/find_references/enums.rs @@ -0,0 +1,71 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +#[test] +fn enum_name() { + test_transform!(find_references, r#" + enum Foo { + Bar, + Baz, + } + + fn main() { + let foo = Foo::Bar; + let foobar: Foo = foo; + } + + fn calc(foo: Foo) {} + + mod rectangle { + use super::Foo; + } + + mod trick { + struct Foo {} + } + "#, @r" + enum Foo { + Bar, + Baz, + } + + fn main() { + let foo = Foo::Bar; + let foobar: Foo = foo; + } + + fn calc(foo: Foo) {} + + mod rectangle { + use super::Foo; + } + + mod trick { + struct Foo {} + } + ") +} + +// FIXME(#164): Pattern should also be selected. +#[test] +fn enum_variants() { + test_transform!(find_references, r#" + enum Foo { Bar, Baz } + fn main() { + let foo = Foo::Bar; + match foo { + Foo::Bar => {} + _ => {} + } + } + "#, @r" + enum Foo { Bar, Baz } + fn main() { + let foo = Foo::Bar; + match foo { + Foo::Bar => {} + _ => {} + } + } + ") +} diff --git a/tests/e2e/find_references/fns.rs b/tests/e2e/find_references/fns.rs new file mode 100644 index 00000000..8ccf84b6 --- /dev/null +++ b/tests/e2e/find_references/fns.rs @@ -0,0 +1,52 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +// FIXME(#129): definition stable ptr for functions is wrong and causes declaration slipping here. +#[test] +fn fn_via_definition() { + test_transform!(find_references, r#" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let x = pow2(2) + pow2(3); + } + "#, @r" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let x = pow2(2) + pow2(3); + } + ") +} + +// FIXME(#129): definition stable ptr for functions is wrong and causes declaration slipping here. +#[test] +fn fn_via_call() { + test_transform!(find_references, r#" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let x = pow2(2) + pow2(3); + } + "#, @r" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let x = pow2(2) + pow2(3); + } + ") +} + +// FIXME(#164): Pattern should not match here. +#[test] +fn unused_function() { + test_transform!(find_references, r#" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let pow2 = 2; + let x = pow2 + pow2; + } + "#, @r" + fn pow2(x: felt252) -> felt252 { x * x } + fn main() { + let pow2 = 2; + let x = pow2 + pow2; + } + ") +} diff --git a/tests/e2e/find_references/macros.rs b/tests/e2e/find_references/macros.rs new file mode 100644 index 00000000..601335b2 --- /dev/null +++ b/tests/e2e/find_references/macros.rs @@ -0,0 +1,24 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +#[test] +fn inline_macro() { + test_transform!(find_references, r#" + fn main() { + print!("Hello world!"); + let arr = array![1, 2, 3, 4, 5]; + } + fn bar() { + let forty_two = array![42]; + } + "#, @r#" + // found several references in the core crate + fn main() { + print!("Hello world!"); + let arr = array![1, 2, 3, 4, 5]; + } + fn bar() { + let forty_two = array![42]; + } + "#) +} diff --git a/tests/e2e/find_references/mod.rs b/tests/e2e/find_references/mod.rs new file mode 100644 index 00000000..4961522c --- /dev/null +++ b/tests/e2e/find_references/mod.rs @@ -0,0 +1,151 @@ +use std::collections::HashSet; +use std::hash::{Hash, Hasher}; + +use itertools::Itertools; +use lsp_types::{ + ClientCapabilities, Location, ReferenceClientCapabilities, ReferenceContext, ReferenceParams, + TextDocumentClientCapabilities, TextDocumentPositionParams, lsp_request, +}; + +use crate::support::cairo_project_toml::CAIRO_PROJECT_TOML_2024_07; +use crate::support::cursor::render_selections_with_attrs; +use crate::support::{cursors, sandbox}; + +mod enums; +mod fns; +mod macros; +mod structs; +mod traits; +mod vars; + +fn caps(base: ClientCapabilities) -> ClientCapabilities { + ClientCapabilities { + text_document: base.text_document.or_else(Default::default).map(|it| { + TextDocumentClientCapabilities { + references: Some(ReferenceClientCapabilities { dynamic_registration: Some(false) }), + ..it + } + }), + ..base + } +} + +fn find_references(cairo_code: &str) -> String { + let (cairo, cursors) = cursors(cairo_code); + + let mut ls = sandbox! { + files { + "cairo_project.toml" => CAIRO_PROJECT_TOML_2024_07, + "src/lib.cairo" => cairo.clone(), + } + client_capabilities = caps; + }; + + ls.open_all_cairo_files_and_wait_for_project_update(); + + assert_eq!(cursors.carets().len(), 1); + let position = cursors.carets()[0]; + + let mut query = |include_declaration: bool| { + let params = ReferenceParams { + text_document_position: TextDocumentPositionParams { + text_document: ls.doc_id("src/lib.cairo"), + position, + }, + context: ReferenceContext { include_declaration }, + work_done_progress_params: Default::default(), + partial_result_params: Default::default(), + }; + let locations = ls.send_request::(params)?; + Some(locations.into_iter().map(LocationForComparison).collect::>()) + }; + + match (query(false), query(true)) { + (None, None) => "none response".into(), + (Some(_), None) => panic!( + "references excluding declaration returned response, but including declaration did not" + ), + (None, Some(_)) => panic!( + "references including declaration returned response, but excluding declaration did not" + ), + (Some(excluding_declaration), Some(including_declaration)) => { + assert!( + excluding_declaration.is_subset(&including_declaration), + "include_declarations: true should return a superset of include_declarations: \ + false" + ); + + let mut declarations: Vec = including_declaration + .difference(&excluding_declaration) + .sorted() + .map(|l| l.0.clone()) + .collect(); + + let mut usages = excluding_declaration + .intersection(&including_declaration) + .sorted() + .map(|l| l.0.clone()) + .collect::>(); + + let mut result = String::new(); + + if remove_core_references(&mut declarations) || remove_core_references(&mut usages) { + result.push_str("// found several references in the core crate\n"); + } + + let ranges = declarations + .into_iter() + .map(|loc| (loc.range, Some("declaration".to_owned()))) + .chain(usages.into_iter().map(|loc| (loc.range, None))) + .collect::>(); + + result += &render_selections_with_attrs(&cairo, &ranges); + + result + } + } +} + +fn remove_core_references(locations: &mut Vec) -> bool { + // Remove any references found in the core crate. + // We do not want to test core crate contents here, but we want to note that they + // exist. + let mut found_core_refs = false; + locations.retain(|loc| { + let path = loc.uri.path(); + if path.contains("/core/src/") || path.contains("/corelib/src/") { + found_core_refs = true; + false + } else { + true + } + }); + found_core_refs +} + +#[derive(PartialEq, Eq)] +struct LocationForComparison(Location); + +impl PartialOrd for LocationForComparison { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for LocationForComparison { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + #[expect(clippy::needless_borrowed_reference)] // Clippy asks to write erroneous code. + let key = |&Self(ref loc)| (loc.uri.as_str(), loc.range.start, loc.range.end); + key(self).cmp(&key(other)) + } +} + +impl Hash for LocationForComparison { + fn hash(&self, state: &mut H) { + self.0.uri.hash(state); + self.0.range.start.line.hash(state); + self.0.range.start.character.hash(state); + self.0.range.end.line.hash(state); + self.0.range.end.character.hash(state); + } +} diff --git a/tests/e2e/find_references/structs.rs b/tests/e2e/find_references/structs.rs new file mode 100644 index 00000000..eca9956e --- /dev/null +++ b/tests/e2e/find_references/structs.rs @@ -0,0 +1,85 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +#[test] +fn struct_by_name() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo { field: felt252 } + fn main() { + let foo: Foo = Foo { field: 0 }; + } + fn calc(foo: Foo) {} + mod rectangle { + use super::Foo; + } + "#, @r" + #[derive(Drop)] + struct Foo { field: felt252 } + fn main() { + let foo: Foo = Foo { field: 0 }; + } + fn calc(foo: Foo) {} + mod rectangle { + use super::Foo; + } + ") +} + +// FIXME(#129): The results for this are very off. +#[test] +fn struct_member_via_definition() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + "#, @r" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + ") +} + +#[test] +fn struct_member_via_constructor() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + "#, @r" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + ") +} + +#[test] +fn struct_member_via_field_access() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + "#, @r" + #[derive(Drop)] + struct Foo { width: u64 } + fn main() { + let foo = Foo { width: 0 }; + let x = foo.width * 2; + } + ") +} diff --git a/tests/e2e/find_references/traits.rs b/tests/e2e/find_references/traits.rs new file mode 100644 index 00000000..65ada3bf --- /dev/null +++ b/tests/e2e/find_references/traits.rs @@ -0,0 +1,238 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +#[test] +fn trait_via_definition() { + test_transform!(find_references, r#" + pub trait ShapeGeometry { + fn area(self: T) -> u64; + } + mod rectangle { + use super::ShapeGeometry; + #[derive(Copy, Drop)] + pub struct Rectangle {} + impl RectangleGeometry of ShapeGeometry { + fn area(self: Rectangle) -> u64 { 0 } + } + } + use rectangle::Rectangle; + fn main() { + let rect = Rectangle {}; + let area = ShapeGeometry::area(rect); + } + "#, @r" + pub trait ShapeGeometry { + fn area(self: T) -> u64; + } + mod rectangle { + use super::ShapeGeometry; + #[derive(Copy, Drop)] + pub struct Rectangle {} + impl RectangleGeometry of ShapeGeometry { + fn area(self: Rectangle) -> u64 { 0 } + } + } + use rectangle::Rectangle; + fn main() { + let rect = Rectangle {}; + let area = ShapeGeometry::area(rect); + } + ") +} + +#[test] +fn trait_method_via_definition() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + "#, @r" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + ") +} + +#[test] +fn trait_method_via_dot_call() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + "#, @r" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + ") +} + +#[test] +fn trait_method_via_path_call() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + "#, @r" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + ") +} + +// FIXME(#170): Does not work as expected. +#[test] +fn impl_method_via_definition() { + test_transform!(find_references, r#" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + "#, @r" + #[derive(Drop)] + struct Foo {} + trait FooTrait { + fn area(self: @Foo) -> u64; + } + impl FooImpl of FooTrait { + fn area(self: @Foo) -> u64 { 0 } + } + #[derive(Drop)] + struct Bar {} + trait BarTrait { + fn area(self: @Bar) -> u64; + } + impl BarImpl of BarTrait { + fn area(self: @Bar) -> u64 { 0 } + } + fn main() { + let foo = Foo {}; + let x = foo.area(); + let y = FooTrait::area(foo); + } + ") +} diff --git a/tests/e2e/find_references/vars.rs b/tests/e2e/find_references/vars.rs new file mode 100644 index 00000000..bcd0d7a9 --- /dev/null +++ b/tests/e2e/find_references/vars.rs @@ -0,0 +1,168 @@ +use crate::find_references::find_references; +use crate::support::insta::test_transform; + +#[test] +fn var_via_binding() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1233; // good + let x = foobar + 1; // good + } + fn bar() { + let foobar = 42; // bad + } + "#, @"none response") +} + +#[test] +fn var_via_use() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1233; // good + let x = foobar + 1; // good + } + fn bar() { + let foobar = 42; // bad + } + "#, @r" + fn main() { + let foobar = 1233; // good + let x = foobar + 1; // good + } + fn bar() { + let foobar = 42; // bad + } + ") +} + +#[test] +fn complex_binding() { + test_transform!(find_references, r#" + fn main() { + let (foobar, foobar2) = (1, 2); // good + let x = foobar + foobar2; // good + let y = foobar2 * foobar2; // bad + let z = foobar2 + foobar; // good + } + "#, @r" + fn main() { + let (foobar, foobar2) = (1, 2); // good + let x = foobar + foobar2; // good + let y = foobar2 * foobar2; // bad + let z = foobar2 + foobar; // good + } + ") +} + +#[test] +fn var_captured_by_closure_outside() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1; + let x = foobar + 1; + let f = |y| x + y + foobar; + } + "#, @r" + fn main() { + let foobar = 1; + let x = foobar + 1; + let f = |y| x + y + foobar; + } + ") +} + +#[test] +fn var_captured_by_closure_inside() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1; + let x = foobar + 1; + let f = |y| x + y + foobar; + } + "#, @r" + fn main() { + let foobar = 1; + let x = foobar + 1; + let f = |y| x + y + foobar; + } + ") +} + +#[test] +fn shadowing1() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1; + let x = foobar + 1; + let foobar = 2; + let y = foobar + 1; + } + "#, @r" + fn main() { + let foobar = 1; + let x = foobar + 1; + let foobar = 2; + let y = foobar + 1; + } + ") +} + +#[test] +fn shadowing2() { + test_transform!(find_references, r#" + fn main() { + let foobar = 1; + let x = foobar + 1; + let foobar = 2; + let y = foobar + 1; + } + "#, @r" + fn main() { + let foobar = 1; + let x = foobar + 1; + let foobar = 2; + let y = foobar + 1; + } + ") +} + +#[test] +fn param_via_binding() { + test_transform!(find_references, r#" + fn pow(num: felt252) -> felt252 { + num * num + } + "#, @r" + fn pow(num: felt252) -> felt252 { + num * num + } + ") +} + +#[test] +fn param_via_use() { + test_transform!(find_references, r#" + fn pow(num: felt252) -> felt252 { + num * num + } + "#, @r" + fn pow(num: felt252) -> felt252 { + num * num + } + ") +} + +#[test] +fn param_captured_by_closure() { + test_transform!(find_references, r#" + fn pow(num: felt252) -> felt252 { + let f = |x| num * x; + num * f(num) + } + "#, @r" + fn pow(num: felt252) -> felt252 { + let f = |x| num * x; + num * f(num) + } + ") +} diff --git a/tests/e2e/main.rs b/tests/e2e/main.rs index 275599ec..d6d0534c 100644 --- a/tests/e2e/main.rs +++ b/tests/e2e/main.rs @@ -1,10 +1,10 @@ mod analysis; mod code_actions; mod completions; +mod find_references; mod goto_definition; mod hover; mod macro_expand; -mod references; mod scarb; mod semantic_tokens; mod support; diff --git a/tests/e2e/references.rs b/tests/e2e/references.rs deleted file mode 100644 index 63d49748..00000000 --- a/tests/e2e/references.rs +++ /dev/null @@ -1,176 +0,0 @@ -use std::collections::HashSet; -use std::hash::{Hash, Hasher}; - -use cairo_lang_test_utils::parse_test_file::TestRunnerResult; -use cairo_lang_utils::ordered_hash_map::OrderedHashMap; -use itertools::Itertools; -use lsp_types::{ - ClientCapabilities, Location, ReferenceClientCapabilities, ReferenceContext, ReferenceParams, - TextDocumentClientCapabilities, TextDocumentPositionParams, lsp_request, -}; - -use crate::support::cairo_project_toml::CAIRO_PROJECT_TOML_2024_07; -use crate::support::cursor::{peek_caret, peek_selection}; -use crate::support::{cursors, sandbox}; - -cairo_lang_test_utils::test_file_test!( - references, - "tests/test_data/references", - { - enum_variants: "enum_variants.txt", - enums: "enums.txt", - fns: "fns.txt", - inline_macros: "inline_macros.txt", - methods: "methods.txt", - struct_members: "struct_members.txt", - structs: "structs.txt", - traits: "traits.txt", - variables: "variables.txt", - }, - test_references -); - -fn caps(base: ClientCapabilities) -> ClientCapabilities { - ClientCapabilities { - text_document: base.text_document.or_else(Default::default).map(|it| { - TextDocumentClientCapabilities { - references: Some(ReferenceClientCapabilities { dynamic_registration: Some(false) }), - ..it - } - }), - ..base - } -} - -fn test_references( - inputs: &OrderedHashMap, - _args: &OrderedHashMap, -) -> TestRunnerResult { - let (cairo, cursors) = cursors(&inputs["cairo_code"]); - - let mut ls = sandbox! { - files { - "cairo_project.toml" => CAIRO_PROJECT_TOML_2024_07, - "src/lib.cairo" => cairo.clone(), - } - client_capabilities = caps; - }; - - ls.open_all_cairo_files_and_wait_for_project_update(); - - let mut outputs = OrderedHashMap::default(); - for (n, position) in cursors.carets().into_iter().enumerate() { - let mut query = |include_declaration: bool| { - let params = ReferenceParams { - text_document_position: TextDocumentPositionParams { - text_document: ls.doc_id("src/lib.cairo"), - position, - }, - context: ReferenceContext { include_declaration }, - work_done_progress_params: Default::default(), - partial_result_params: Default::default(), - }; - let locations = ls.send_request::(params)?; - Some(locations.into_iter().map(LocationForComparison).collect::>()) - }; - - let mut report = String::new(); - report.push_str(&peek_caret(&cairo, position)); - - match (query(false), query(true)) { - (None, None) => report.push_str("none response"), - (Some(_), None) => panic!( - "references excluding declaration returned response, but including declaration \ - did not" - ), - (None, Some(_)) => panic!( - "references including declaration returned response, but excluding declaration \ - did not" - ), - (Some(excluding_declaration), Some(including_declaration)) => { - assert!( - excluding_declaration.is_subset(&including_declaration), - "include_declarations: true should return a superset of include_declarations: \ - false" - ); - - let mut declarations: Vec = including_declaration - .difference(&excluding_declaration) - .sorted() - .map(|l| l.0.clone()) - .collect(); - - let mut usages = excluding_declaration - .intersection(&including_declaration) - .sorted() - .map(|l| l.0.clone()) - .collect::>(); - - report.push_str("\nDECLARATIONS:\n"); - - remove_core_references(&mut declarations, &mut report); - - for location in declarations { - report.push_str(&peek_selection(&cairo, &location.range)); - } - - report.push_str("\nUSAGES:\n"); - - remove_core_references(&mut usages, &mut report); - - for location in usages { - report.push_str(&peek_selection(&cairo, &location.range)); - } - } - } - - outputs.insert(format!("References #{n}"), report); - } - TestRunnerResult::success(outputs) -} - -fn remove_core_references(locations: &mut Vec, report: &mut String) { - // Remove any references found in the core crate. - // We do not want to test core crate contents here, but we want to note that they - // exist. - let mut found_core_refs = false; - locations.retain(|loc| { - let path = loc.uri.path(); - if path.contains("/core/src/") || path.contains("/corelib/src/") { - found_core_refs = true; - false - } else { - true - } - }); - if found_core_refs { - report.push_str("found several references in the core crate\n"); - } -} - -#[derive(PartialEq, Eq)] -struct LocationForComparison(Location); - -impl PartialOrd for LocationForComparison { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for LocationForComparison { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - #[expect(clippy::needless_borrowed_reference)] // Clippy asks to write erroneous code. - let key = |&Self(ref loc)| (loc.uri.as_str(), loc.range.start, loc.range.end); - key(self).cmp(&key(other)) - } -} - -impl Hash for LocationForComparison { - fn hash(&self, state: &mut H) { - self.0.uri.hash(state); - self.0.range.start.line.hash(state); - self.0.range.start.character.hash(state); - self.0.range.end.line.hash(state); - self.0.range.end.character.hash(state); - } -} diff --git a/tests/e2e/support/cursor.rs b/tests/e2e/support/cursor.rs index 3359f22f..255cd072 100644 --- a/tests/e2e/support/cursor.rs +++ b/tests/e2e/support/cursor.rs @@ -124,19 +124,33 @@ pub fn peek_selection(text: &str, range: &Range) -> String { /// Adds selection markers for all ranges to the source text. pub fn render_selections(text: &str, ranges: &[Range]) -> String { + render_selections_with_attrs( + text, + &ranges.iter().map(|range| (*range, None)).collect::>(), + ) +} + +/// Adds selection markers for all ranges to the source text with optional attributes to attach. +pub fn render_selections_with_attrs(text: &str, ranges: &[(Range, Option)]) -> String { let mut text = text.to_owned(); ranges .iter() - .flat_map(|range| { + .flat_map(|(range, attr)| { assert!(range.start <= range.end); [ - (index_in_text(&text, range.start), ""), - (index_in_text(&text, range.end), ""), + ( + index_in_text(&text, range.start), + format!( + "", + attr = attr.as_ref().map(|val| format!("={val}")).unwrap_or_default() + ), + ), + (index_in_text(&text, range.end), "".to_owned()), ] }) .sorted_by_key(|(idx, _)| *idx) .fold(0, |offset, (idx, marker)| { - text.insert_str(idx + offset, marker); + text.insert_str(idx + offset, &marker); offset + marker.len() }); text diff --git a/tests/test_data/references/enum_variants.txt b/tests/test_data/references/enum_variants.txt deleted file mode 100644 index 3abfcfac..00000000 --- a/tests/test_data/references/enum_variants.txt +++ /dev/null @@ -1,26 +0,0 @@ -//! > Test references of enum variants. - -//! > test_runner_name -test_references - -//! > cairo_code -enum Foo { - Bar, - Baz, -} - -fn main() { - let foo = Foo::Bar; - match foo { - Foo::Bar => {} // FIXME(#164): This should work. - _ => {} - } -} - -//! > References #0 - let foo = Foo::Bar; - -DECLARATIONS: - Bar, - -USAGES: diff --git a/tests/test_data/references/enums.txt b/tests/test_data/references/enums.txt deleted file mode 100644 index b89a0225..00000000 --- a/tests/test_data/references/enums.txt +++ /dev/null @@ -1,101 +0,0 @@ -//! > Test find references of an enum. - -//! > test_runner_name -test_references - -//! > cairo_code -enum Foo { - Bar, - Baz, -} - -fn main() { - let foo = Foo::Bar; - let foobar: Foo = foo; -} - -fn calc(foo: Foo) {} - -mod rectangle { - use super::Foo; -} - -//! > References #0 -enum Foo { - -DECLARATIONS: -enum Foo { - Bar, - Baz, -} - -USAGES: -enum Foo { - let foo = Foo::Bar; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #1 - let foo = Foo::Bar; - -DECLARATIONS: -enum Foo { - Bar, - Baz, -} - -USAGES: -enum Foo { - let foo = Foo::Bar; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #2 - let foobar: Foo = foo; - -DECLARATIONS: -enum Foo { - Bar, - Baz, -} - -USAGES: -enum Foo { - let foo = Foo::Bar; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #3 -fn calc(foo: Foo) {} - -DECLARATIONS: -enum Foo { - Bar, - Baz, -} - -USAGES: -enum Foo { - let foo = Foo::Bar; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #4 - use super::Foo; - -DECLARATIONS: -enum Foo { - Bar, - Baz, -} - -USAGES: -enum Foo { - let foo = Foo::Bar; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; diff --git a/tests/test_data/references/fns.txt b/tests/test_data/references/fns.txt deleted file mode 100644 index bb34af6a..00000000 --- a/tests/test_data/references/fns.txt +++ /dev/null @@ -1,152 +0,0 @@ -//! > Test references of function. - -//! > test_runner_name -test_references - -//! > cairo_code -// FIXME(#129): definition stable ptr for functions is wrong and causes declaration slipping here. -fn pow2(x: felt252) -> felt252 { x * x } - -fn main() { - let x = pow2(2) + pow2(3); -} - -//! > References #0 -fn pow2(x: felt252) -> felt252 { x * x } - -DECLARATIONS: -fn pow2(x: felt252) -> felt252 { x * x } - -USAGES: -fn pow2(x: felt252) -> felt252 { x * x } - let x = pow2(2) + pow2(3); - let x = pow2(2) + pow2(3); - -//! > References #1 - let x = pow2(2) + pow2(3); - -DECLARATIONS: -fn pow2(x: felt252) -> felt252 { x * x } - -USAGES: -fn pow2(x: felt252) -> felt252 { x * x } - let x = pow2(2) + pow2(3); - let x = pow2(2) + pow2(3); - -//! > ========================================================================== - -//! > Test unused function. - -//! > test_runner_name -test_references - -//! > cairo_code -fn pow2(x: felt252) -> felt252 { x * x } - -fn main() { - let pow2 = 2; // bad // FIXME(mkaput): Why this? - let x = pow2 + pow2; // bad -} - -//! > References #0 -fn pow2(x: felt252) -> felt252 { x * x } - -DECLARATIONS: -fn pow2(x: felt252) -> felt252 { x * x } - -USAGES: -fn pow2(x: felt252) -> felt252 { x * x } - let pow2 = 2; // bad // FIXME(mkaput): Why this? - -//! > ========================================================================== - -//! > Test multiple function usages in a single line. - -//! > test_runner_name -test_references - -//! > cairo_code -fn pow2(x: felt252) -> felt252 { x * x } - -fn main() { - let x = pow2(2) + pow2(3); -} - -//! > References #0 -fn pow2(x: felt252) -> felt252 { x * x } - -DECLARATIONS: -fn pow2(x: felt252) -> felt252 { x * x } - -USAGES: -fn pow2(x: felt252) -> felt252 { x * x } - let x = pow2(2) + pow2(3); - let x = pow2(2) + pow2(3); - -//! > ========================================================================== - -//! > Test references of function parameter. - -//! > test_runner_name -test_references - -//! > cairo_code -fn pow(num: felt252) -> felt252 { - num * num -} - -//! > References #0 -fn pow(num: felt252) -> felt252 { - -DECLARATIONS: -fn pow(num: felt252) -> felt252 { - num * num -} - -USAGES: -fn pow(num: felt252) -> felt252 { - -//! > References #1 - num * num - -DECLARATIONS: -fn pow(num: felt252) -> felt252 { - -USAGES: - num * num - num * num - -//! > ========================================================================== - -//! > Test references of function parameter captured by a closure. - -//! > test_runner_name -test_references - -//! > cairo_code -fn pow(num: felt252) -> felt252 { - let f = |x| num * x; - num * f(num) -} - -//! > References #0 - let f = |x| num * x; - -DECLARATIONS: -fn pow(num: felt252) -> felt252 { - -USAGES: - let f = |x| num * x; - num * f(num) - num * f(num) - -//! > References #1 - num * f(num) - -DECLARATIONS: -fn pow(num: felt252) -> felt252 { - -USAGES: - let f = |x| num * x; - num * f(num) - num * f(num) diff --git a/tests/test_data/references/inline_macros.txt b/tests/test_data/references/inline_macros.txt deleted file mode 100644 index a525611c..00000000 --- a/tests/test_data/references/inline_macros.txt +++ /dev/null @@ -1,24 +0,0 @@ -//! > Test references of inline macro. - -//! > test_runner_name -test_references - -//! > cairo_code -fn main() { - print!("Hello world!"); - let arr = array![1, 2, 3, 4, 5]; -} - -fn bar() { - let forty_two = array![42]; -} - -//! > References #0 - let arr = array![1, 2, 3, 4, 5]; - -DECLARATIONS: - -USAGES: -found several references in the core crate - let arr = array![1, 2, 3, 4, 5]; - let forty_two = array![42]; diff --git a/tests/test_data/references/methods.txt b/tests/test_data/references/methods.txt deleted file mode 100644 index 700e9661..00000000 --- a/tests/test_data/references/methods.txt +++ /dev/null @@ -1,79 +0,0 @@ -//! > Test references of methods. - -//! > test_runner_name -test_references - -//! > cairo_code -#[derive(Drop)] -struct Foo {} - -trait FooTrait { - fn area(self: @Foo) -> u64; -} - -impl FooImpl of FooTrait { - // FIXME(#170): Does not work as expected. - fn area(self: @Foo) -> u64 { 0 } -} - -#[derive(Drop)] -struct Bar {} - -trait BarTrait { - fn area(self: @Bar) -> u64; -} - -impl BarImpl of BarTrait { - fn area(self: @Bar) -> u64 { 0 } -} - -fn main() { - let foo = Foo {}; - let x = foo.area(); - let y = FooTrait::area(foo); -} - -//! > References #0 - fn area(self: @Foo) -> u64; - -DECLARATIONS: - fn area(self: @Foo) -> u64; - -USAGES: - fn area(self: @Foo) -> u64; - let x = foo.area(); - let y = FooTrait::area(foo); - -//! > References #1 - fn area(self: @Foo) -> u64 { 0 } - -DECLARATIONS: -impl FooImpl of FooTrait { - // FIXME(#170): Does not work as expected. - fn area(self: @Foo) -> u64 { 0 } -} - -USAGES: -impl FooImpl of FooTrait { - -//! > References #2 - let x = foo.area(); - -DECLARATIONS: - fn area(self: @Foo) -> u64; - -USAGES: - fn area(self: @Foo) -> u64; - let x = foo.area(); - let y = FooTrait::area(foo); - -//! > References #3 - let y = FooTrait::area(foo); - -DECLARATIONS: - fn area(self: @Foo) -> u64; - -USAGES: - fn area(self: @Foo) -> u64; - let x = foo.area(); - let y = FooTrait::area(foo); diff --git a/tests/test_data/references/struct_members.txt b/tests/test_data/references/struct_members.txt deleted file mode 100644 index a0110c52..00000000 --- a/tests/test_data/references/struct_members.txt +++ /dev/null @@ -1,56 +0,0 @@ -//! > Test references of struct members. - -//! > test_runner_name -test_references - -//! > cairo_code -#[derive(Drop)] -struct Rectangle { - // FIXME(#129): The results for this are very off. - width: u64, - height: u64, -} - -fn main() { - let rectangle = Rectangle { width: 0, height: 0 }; -} - -fn calculate_area(rectangle: Rectangle) -> u64 { - rectangle.width * rectangle.height -} - -//! > References #0 - width: u64, - -DECLARATIONS: -#[derive(Drop)] -struct Rectangle { - // FIXME(#129): The results for this are very off. - width: u64, - height: u64, -} - -USAGES: -struct Rectangle { - let rectangle = Rectangle { width: 0, height: 0 }; -fn calculate_area(rectangle: Rectangle) -> u64 { - -//! > References #1 - let rectangle = Rectangle { width: 0, height: 0 }; - -DECLARATIONS: - width: u64, - -USAGES: - let rectangle = Rectangle { width: 0, height: 0 }; - rectangle.width * rectangle.height - -//! > References #2 - rectangle.width * rectangle.height - -DECLARATIONS: - width: u64, - -USAGES: - let rectangle = Rectangle { width: 0, height: 0 }; - rectangle.width * rectangle.height diff --git a/tests/test_data/references/structs.txt b/tests/test_data/references/structs.txt deleted file mode 100644 index b7e7bbc0..00000000 --- a/tests/test_data/references/structs.txt +++ /dev/null @@ -1,95 +0,0 @@ -//! > Test find references of a struct. - -//! > test_runner_name -test_references - -//! > cairo_code -struct Foo { - field: felt252, -} - -fn main() { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -} - -fn calc(foo: Foo) {} - -mod rectangle { - use super::Foo; -} - -//! > References #0 -struct Foo { - -DECLARATIONS: -struct Foo { - field: felt252, -} - -USAGES: -struct Foo { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #1 - let foo = Foo { field: 0 }; - -DECLARATIONS: -struct Foo { - field: felt252, -} - -USAGES: -struct Foo { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #2 - let foobar: Foo = foo; - -DECLARATIONS: -struct Foo { - field: felt252, -} - -USAGES: -struct Foo { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #3 -fn calc(foo: Foo) {} - -DECLARATIONS: -struct Foo { - field: felt252, -} - -USAGES: -struct Foo { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; - -//! > References #4 - use super::Foo; - -DECLARATIONS: -struct Foo { - field: felt252, -} - -USAGES: -struct Foo { - let foo = Foo { field: 0 }; - let foobar: Foo = foo; -fn calc(foo: Foo) {} - use super::Foo; diff --git a/tests/test_data/references/traits.txt b/tests/test_data/references/traits.txt deleted file mode 100644 index 552cb4f6..00000000 --- a/tests/test_data/references/traits.txt +++ /dev/null @@ -1,69 +0,0 @@ -//! > Test find references of a trait. - -//! > test_runner_name -test_references - -//! > cairo_code -pub trait ShapeGeometry { - fn area(self: T) -> u64; -} - -mod rectangle { - use super::ShapeGeometry; - - #[derive(Copy, Drop)] - pub struct Rectangle {} - - impl RectangleGeometry of ShapeGeometry { - fn area(self: Rectangle) -> u64 { 0 } - } -} - -use rectangle::Rectangle; - -fn main() { - let rect = Rectangle {}; - let area = ShapeGeometry::area(rect); -} - -//! > References #0 - use super::ShapeGeometry; - -DECLARATIONS: -pub trait ShapeGeometry { - fn area(self: T) -> u64; -} - -USAGES: -pub trait ShapeGeometry { - use super::ShapeGeometry; - impl RectangleGeometry of ShapeGeometry { - let area = ShapeGeometry::area(rect); - -//! > References #1 - impl RectangleGeometry of ShapeGeometry { - -DECLARATIONS: -pub trait ShapeGeometry { - fn area(self: T) -> u64; -} - -USAGES: -pub trait ShapeGeometry { - use super::ShapeGeometry; - impl RectangleGeometry of ShapeGeometry { - let area = ShapeGeometry::area(rect); - -//! > References #2 - let area = ShapeGeometry::area(rect); - -DECLARATIONS: -pub trait ShapeGeometry { - fn area(self: T) -> u64; -} - -USAGES: -pub trait ShapeGeometry { - use super::ShapeGeometry; - impl RectangleGeometry of ShapeGeometry { - let area = ShapeGeometry::area(rect); diff --git a/tests/test_data/references/variables.txt b/tests/test_data/references/variables.txt deleted file mode 100644 index 53e577a2..00000000 --- a/tests/test_data/references/variables.txt +++ /dev/null @@ -1,90 +0,0 @@ -//! > Test references of variables. - -//! > test_runner_name -test_references - -//! > cairo_code -fn main() { - let foobar = 1233; // bad - let x = foobar + 1; // good - bar(); - let y = x + foobar * foobar; // good -} - -fn bar() { - let foobar = 42; // bad -} - -//! > References #0 - let foobar = 1233; // bad -none response - -//! > References #1 - let x = foobar + 1; // good - -DECLARATIONS: - let foobar = 1233; // bad - -USAGES: - let x = foobar + 1; // good - let y = x + foobar * foobar; // good - let y = x + foobar * foobar; // good - -//! > ========================================================================== - -//! > Test references of variable declared via a complex pattern. - -//! > test_runner_name -test_references - -//! > cairo_code -fn main() { - let (foobar, foobar2) = (1, 2); // good - let x = foobar + foobar2; // good - let y = foobar2 * foobar2; // bad - let z = foobar2 + foobar; // good -} - -//! > References #0 - let x = foobar + foobar2; // good - -DECLARATIONS: - let (foobar, foobar2) = (1, 2); // good - -USAGES: - let x = foobar + foobar2; // good - let z = foobar2 + foobar; // good - -//! > ========================================================================== - -//! > Test references of variable captured by a closure; - -//! > test_runner_name -test_references - -//! > cairo_code -fn main() { - let foobar = 1; - let x = foobar + 1; - let f = |y| x + y + foobar; -} - -//! > References #0 - let x = foobar + 1; - -DECLARATIONS: - let foobar = 1; - -USAGES: - let x = foobar + 1; - let f = |y| x + y + foobar; - -//! > References #1 - let f = |y| x + y + foobar; - -DECLARATIONS: - let foobar = 1; - -USAGES: - let x = foobar + 1; - let f = |y| x + y + foobar;