From c6ed325ebe0343d14150386f57cf141c9a7c9441 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 25 Nov 2024 13:44:08 -0300 Subject: [PATCH 1/4] fix: LSP code action wasn't triggering on beginning or end of identifier --- compiler/noirc_errors/src/position.rs | 2 +- .../requests/code_action/import_or_qualify.rs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_errors/src/position.rs b/compiler/noirc_errors/src/position.rs index 8131db323b9..42492a7e9a2 100644 --- a/compiler/noirc_errors/src/position.rs +++ b/compiler/noirc_errors/src/position.rs @@ -95,7 +95,7 @@ impl Span { } pub fn intersects(&self, other: &Span) -> bool { - self.end() > other.start() && self.start() < other.end() + self.end() >= other.start() && self.start() <= other.end() } pub fn is_smaller(&self, other: &Span) -> bool { diff --git a/tooling/lsp/src/requests/code_action/import_or_qualify.rs b/tooling/lsp/src/requests/code_action/import_or_qualify.rs index ffc83b05a5b..609a81bdfe7 100644 --- a/tooling/lsp/src/requests/code_action/import_or_qualify.rs +++ b/tooling/lsp/src/requests/code_action/import_or_qualify.rs @@ -183,6 +183,31 @@ mod foo { } } +fn foo(x: SomeTypeInBar) {}"#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_import_code_action_for_struct_at_beginning_of_name() { + let title = "Import foo::bar::SomeTypeInBar"; + + let src = r#"mod foo { + pub mod bar { + pub struct SomeTypeInBar {} + } +} + +fn foo(x: >| Date: Mon, 25 Nov 2024 16:23:12 -0300 Subject: [PATCH 2/4] Add tests and comments --- compiler/noirc_errors/src/position.rs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/compiler/noirc_errors/src/position.rs b/compiler/noirc_errors/src/position.rs index 42492a7e9a2..6b2365912d4 100644 --- a/compiler/noirc_errors/src/position.rs +++ b/compiler/noirc_errors/src/position.rs @@ -94,6 +94,9 @@ impl Span { self.start() <= other.start() && self.end() >= other.end() } + /// Returns `true` if any point of `self` intersects a point of `other`. + /// If either span is empty, the point where the span is empty is considered + /// to be part of the span (so, for example, `1..1` intersects `1..3`). pub fn intersects(&self, other: &Span) -> bool { self.end() >= other.start() && self.start() <= other.end() } @@ -140,3 +143,37 @@ impl Location { self.file == other.file && self.span.contains(&other.span) } } + +#[cfg(test)] +mod tests { + use crate::Span; + + #[test] + fn test_intersects() { + assert!(Span::from(5..10).intersects(&Span::from(5..10))); + + assert!(Span::from(5..10).intersects(&Span::from(5..5))); + assert!(Span::from(5..5).intersects(&Span::from(5..10))); + + assert!(Span::from(10..10).intersects(&Span::from(5..10))); + assert!(Span::from(5..10).intersects(&Span::from(10..10))); + + assert!(Span::from(5..10).intersects(&Span::from(6..9))); + assert!(Span::from(6..9).intersects(&Span::from(5..10))); + + assert!(Span::from(5..10).intersects(&Span::from(4..11))); + assert!(Span::from(4..11).intersects(&Span::from(5..10))); + + assert!(Span::from(5..10).intersects(&Span::from(4..6))); + assert!(Span::from(4..6).intersects(&Span::from(5..10))); + + assert!(Span::from(5..10).intersects(&Span::from(9..11))); + assert!(Span::from(9..11).intersects(&Span::from(5..10))); + + assert!(!Span::from(5..10).intersects(&Span::from(3..4))); + assert!(!Span::from(3..4).intersects(&Span::from(5..10))); + + assert!(!Span::from(5..10).intersects(&Span::from(11..12))); + assert!(!Span::from(11..12).intersects(&Span::from(5..10))); + } +} From eb456bce1a57080cf21ffe11f2c0d38e19d172e7 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 26 Nov 2024 15:59:38 -0300 Subject: [PATCH 3/4] Add a comment for when both spans are empty --- compiler/noirc_errors/src/position.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/noirc_errors/src/position.rs b/compiler/noirc_errors/src/position.rs index 6b2365912d4..bbfc0897990 100644 --- a/compiler/noirc_errors/src/position.rs +++ b/compiler/noirc_errors/src/position.rs @@ -97,6 +97,8 @@ impl Span { /// Returns `true` if any point of `self` intersects a point of `other`. /// If either span is empty, the point where the span is empty is considered /// to be part of the span (so, for example, `1..1` intersects `1..3`). + /// If both spans are empty, they are considered to intersect if they are the same + /// span (so `1..1` intersects `1..1`). pub fn intersects(&self, other: &Span) -> bool { self.end() >= other.start() && self.start() <= other.end() } From c8c1e857a91e1dfa731947a304a8ff0f93a5e5fb Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 27 Nov 2024 06:55:40 -0300 Subject: [PATCH 4/4] Update comment --- compiler/noirc_errors/src/position.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/noirc_errors/src/position.rs b/compiler/noirc_errors/src/position.rs index bbfc0897990..c7a64c4f422 100644 --- a/compiler/noirc_errors/src/position.rs +++ b/compiler/noirc_errors/src/position.rs @@ -95,10 +95,7 @@ impl Span { } /// Returns `true` if any point of `self` intersects a point of `other`. - /// If either span is empty, the point where the span is empty is considered - /// to be part of the span (so, for example, `1..1` intersects `1..3`). - /// If both spans are empty, they are considered to intersect if they are the same - /// span (so `1..1` intersects `1..1`). + /// Adjacent spans are considered to intersect (so, for example, `0..1` intersects `1..3`). pub fn intersects(&self, other: &Span) -> bool { self.end() >= other.start() && self.start() <= other.end() }