Skip to content

Commit 4625f3f

Browse files
giacomocavalierilpil
authored andcommitted
add collapse case code action
1 parent 7ef7e0b commit 4625f3f

16 files changed

+935
-13
lines changed

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,39 @@
234234
colon in the rename dialog (`name:` -> `name`)
235235
([fruno](https://github.com/frunobulax-the-poodle))
236236

237+
- The language server now offers a code action to collapse nested case
238+
expressions. Take this example:
239+
240+
```gleam
241+
case user {
242+
User(role: Admin, name:) ->
243+
// Here the only thing we're doing is pattern matching on the
244+
// `name` variable we've just defined in the outer pattern.
245+
case name {
246+
"Joe" -> "Hello, Joe!"
247+
_ -> "Hello, stranger"
248+
}
249+
250+
_ -> "You're not an admin!"
251+
}
252+
```
253+
254+
We could simplify this case expression and reduce nesting like so:
255+
256+
```gleam
257+
case user {
258+
User(role: Admin, name: "Joe") -> "Hello, Joe!"
259+
User(role: Admin, name: _) -> "Hello, stranger"
260+
_ -> "You're not an admin!"
261+
}
262+
```
263+
264+
Now, if you hover over that pattern, the language server will offer the
265+
"collapse nested case" action that will simplify your code like shown in the
266+
example above.
267+
268+
([Giacomo Cavalieri](https://github.com/giacomocavalieri))
269+
237270
### Formatter
238271

239272
- The formatter now removes needless multiple negations that are safe to remove.

compiler-core/src/ast.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,24 +2707,28 @@ impl TypedPattern {
27072707
}
27082708
}
27092709

2710-
pub fn bound_variables(&self) -> Vec<EcoString> {
2710+
pub fn bound_variables(&self) -> Vec<(EcoString, SrcSpan)> {
27112711
let mut variables = Vec::new();
27122712
self.collect_bound_variables(&mut variables);
27132713
variables
27142714
}
27152715

2716-
fn collect_bound_variables(&self, variables: &mut Vec<EcoString>) {
2716+
fn collect_bound_variables(&self, variables: &mut Vec<(EcoString, SrcSpan)>) {
27172717
match self {
27182718
Pattern::Int { .. }
27192719
| Pattern::Float { .. }
27202720
| Pattern::String { .. }
27212721
| Pattern::Discard { .. }
27222722
| Pattern::Invalid { .. } => {}
27232723

2724-
Pattern::Variable { name, .. } => variables.push(name.clone()),
2724+
Pattern::Variable { name, location, .. } => variables.push((name.clone(), *location)),
27252725
Pattern::BitArraySize { .. } => {}
2726-
Pattern::Assign { name, pattern, .. } => {
2727-
variables.push(name.clone());
2726+
Pattern::Assign {
2727+
name,
2728+
pattern,
2729+
location,
2730+
} => {
2731+
variables.push((name.clone(), *location));
27282732
pattern.collect_bound_variables(variables);
27292733
}
27302734
Pattern::List { elements, tail, .. } => {
@@ -2753,13 +2757,14 @@ impl TypedPattern {
27532757
Pattern::StringPrefix {
27542758
left_side_assignment,
27552759
right_side_assignment,
2760+
right_location,
27562761
..
27572762
} => {
2758-
if let Some((left_variable, _)) = left_side_assignment {
2759-
variables.push(left_variable.clone());
2763+
if let Some(assignment) = left_side_assignment {
2764+
variables.push(assignment.clone());
27602765
}
27612766
match right_side_assignment {
2762-
AssignName::Variable(name) => variables.push(name.clone()),
2767+
AssignName::Variable(name) => variables.push((name.clone(), *right_location)),
27632768
AssignName::Discard(_) => {}
27642769
}
27652770
}

compiler-core/src/javascript/decision.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ pub fn let_<'a>(
702702
// We must generate this after we generate the code for the decision tree
703703
// itself as we might be re-binding variables which are used in the checks
704704
// to determine whether the pattern matches or not.
705-
let beginning_assignments = pattern.bound_variables().into_iter().map(|variable| {
705+
let beginning_assignments = pattern.bound_variables().into_iter().map(|(variable, _)| {
706706
docvec![
707707
"let ",
708708
expression_generator.local_var(&variable),

0 commit comments

Comments
 (0)