Skip to content

Commit 718c9ad

Browse files
giacomocavalierilpil
authored andcommitted
properly deal with patterns using labels and the label shorthand syntax
1 parent 5c2bff1 commit 718c9ad

5 files changed

+156
-3
lines changed

compiler-core/src/ast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,9 +1536,9 @@ where
15361536
/// If the call arg is defined using a label shorthand, this will return the
15371537
/// label name.
15381538
///
1539-
fn label_shorthand_name(&self) -> Option<EcoString> {
1539+
pub fn label_shorthand_name(&self) -> Option<&EcoString> {
15401540
if !self.is_implicit() && self.location == self.value.location() {
1541-
self.label.clone()
1541+
self.label.as_ref()
15421542
} else {
15431543
None
15441544
}
@@ -2792,7 +2792,7 @@ impl TypedPattern {
27922792
for argument in arguments {
27932793
if let Some(name) = argument.label_shorthand_name() {
27942794
variables.push(BoundVariable::ShorthandLabel {
2795-
name,
2795+
name: name.clone(),
27962796
location: argument.location,
27972797
})
27982798
} else {

compiler-core/src/language_server/code_action.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,6 +4567,15 @@ where
45674567
.iter()
45684568
.map(|pattern| {
45694569
let mut clause_code = clause_code.to_string();
4570+
// If we're replacing a variable that's using the shorthand
4571+
// syntax we want to add a space to separate it from the
4572+
// preceding `:`.
4573+
let pattern = if variable_start == variable_end {
4574+
&eco_format!(" {pattern}")
4575+
} else {
4576+
pattern
4577+
};
4578+
45704579
clause_code.replace_range(variable_start..variable_end, pattern);
45714580
clause_code
45724581
})
@@ -4886,6 +4895,24 @@ where
48864895
}
48874896
}
48884897

4898+
fn visit_typed_pattern_call_arg(&mut self, arg: &'ast CallArg<TypedPattern>) {
4899+
if let Some(name) = arg.label_shorthand_name()
4900+
&& within(
4901+
self.params.range,
4902+
self.edits.src_span_to_lsp_range(arg.location),
4903+
)
4904+
{
4905+
let location = SrcSpan {
4906+
start: arg.location.end,
4907+
end: arg.location.end,
4908+
};
4909+
self.pattern_variable_under_cursor = Some((name, location, arg.value.type_()));
4910+
return;
4911+
}
4912+
4913+
ast::visit::visit_typed_pattern_call_arg(self, arg);
4914+
}
4915+
48894916
fn visit_typed_pattern_string_prefix(
48904917
&mut self,
48914918
_location: &'ast SrcSpan,

compiler-core/src/language_server/tests/action.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6991,6 +6991,54 @@ fn maybe_wibble() { Ok(Wobble) }
69916991
);
69926992
}
69936993

6994+
#[test]
6995+
fn pattern_match_on_clause_variable_with_label() {
6996+
assert_code_action!(
6997+
PATTERN_MATCH_ON_VARIABLE,
6998+
"
6999+
pub fn main() {
7000+
case wibble() {
7001+
Wobble(wibble: something) -> 1
7002+
_ -> 2
7003+
}
7004+
}
7005+
7006+
type Wibble {
7007+
Wobble(wibble: Wibble)
7008+
Woo
7009+
}
7010+
7011+
fn new() { Wobble }
7012+
7013+
",
7014+
find_position_of("something").to_selection()
7015+
);
7016+
}
7017+
7018+
#[test]
7019+
fn pattern_match_on_clause_variable_with_label_shorthand() {
7020+
assert_code_action!(
7021+
PATTERN_MATCH_ON_VARIABLE,
7022+
"
7023+
pub fn main() {
7024+
case new() {
7025+
Wobble(wibble:) -> 1
7026+
_ -> 2
7027+
}
7028+
}
7029+
7030+
type Wibble {
7031+
Wobble(wibble: Wibble)
7032+
Woo
7033+
}
7034+
7035+
fn new() { Wobble }
7036+
7037+
",
7038+
find_position_of("wibble").to_selection()
7039+
);
7040+
}
7041+
69947042
#[test]
69957043
fn pattern_match_on_clause_variable_nested_pattern() {
69967044
assert_code_action!(
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn main() {\n case wibble() {\n Wobble(wibble: something) -> 1\n _ -> 2\n }\n}\n\ntype Wibble {\n Wobble(wibble: Wibble)\n Woo\n}\n\nfn new() { Wobble }\n\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn main() {
8+
case wibble() {
9+
Wobble(wibble: something) -> 1
10+
11+
_ -> 2
12+
}
13+
}
14+
15+
type Wibble {
16+
Wobble(wibble: Wibble)
17+
Woo
18+
}
19+
20+
fn new() { Wobble }
21+
22+
23+
24+
----- AFTER ACTION
25+
26+
pub fn main() {
27+
case wibble() {
28+
Wobble(wibble: Wobble(wibble:)) -> 1
29+
Wobble(wibble: Woo) -> 1
30+
_ -> 2
31+
}
32+
}
33+
34+
type Wibble {
35+
Wobble(wibble: Wibble)
36+
Woo
37+
}
38+
39+
fn new() { Wobble }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn main() {\n case new() {\n Wobble(wibble:) -> 1\n _ -> 2\n }\n}\n\ntype Wibble {\n Wobble(wibble: Wibble)\n Woo\n}\n\nfn new() { Wobble }\n\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn main() {
8+
case new() {
9+
Wobble(wibble:) -> 1
10+
11+
_ -> 2
12+
}
13+
}
14+
15+
type Wibble {
16+
Wobble(wibble: Wibble)
17+
Woo
18+
}
19+
20+
fn new() { Wobble }
21+
22+
23+
24+
----- AFTER ACTION
25+
26+
pub fn main() {
27+
case new() {
28+
Wobble(wibble: Wobble(wibble:)) -> 1
29+
Wobble(wibble: Woo) -> 1
30+
_ -> 2
31+
}
32+
}
33+
34+
type Wibble {
35+
Wobble(wibble: Wibble)
36+
Woo
37+
}
38+
39+
fn new() { Wobble }

0 commit comments

Comments
 (0)