Skip to content

Commit 24b2ae2

Browse files
GearsDatapackslpil
authored andcommitted
Track all possible references to variables
1 parent f0ead7e commit 24b2ae2

4 files changed

+167
-16
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8679,22 +8679,47 @@ impl<'ast> ast::visit::Visit<'ast> for ExtractFunction<'ast> {
86798679
constructor: &'ast ValueConstructor,
86808680
name: &'ast EcoString,
86818681
) {
8682-
match &constructor.variant {
8683-
type_::ValueConstructorVariant::LocalVariable {
8684-
location: definition_location,
8685-
..
8686-
} => {
8687-
self.register_referenced_variable(
8688-
name,
8689-
&constructor.type_,
8690-
*location,
8691-
*definition_location,
8692-
);
8693-
}
8694-
type_::ValueConstructorVariant::ModuleConstant { .. }
8695-
| type_::ValueConstructorVariant::LocalConstant { .. }
8696-
| type_::ValueConstructorVariant::ModuleFn { .. }
8697-
| type_::ValueConstructorVariant::Record { .. } => {}
8682+
if let type_::ValueConstructorVariant::LocalVariable {
8683+
location: definition_location,
8684+
..
8685+
} = &constructor.variant
8686+
{
8687+
self.register_referenced_variable(
8688+
name,
8689+
&constructor.type_,
8690+
*location,
8691+
*definition_location,
8692+
);
8693+
}
8694+
}
8695+
8696+
fn visit_typed_clause_guard_var(
8697+
&mut self,
8698+
location: &'ast SrcSpan,
8699+
name: &'ast EcoString,
8700+
type_: &'ast Arc<Type>,
8701+
definition_location: &'ast SrcSpan,
8702+
) {
8703+
self.register_referenced_variable(name, type_, *location, *definition_location);
8704+
}
8705+
8706+
fn visit_typed_bit_array_size_variable(
8707+
&mut self,
8708+
location: &'ast SrcSpan,
8709+
name: &'ast EcoString,
8710+
constructor: &'ast Option<Box<ValueConstructor>>,
8711+
type_: &'ast Arc<Type>,
8712+
) {
8713+
let variant = match constructor {
8714+
Some(constructor) => &constructor.variant,
8715+
None => return,
8716+
};
8717+
if let type_::ValueConstructorVariant::LocalVariable {
8718+
location: definition_location,
8719+
..
8720+
} = variant
8721+
{
8722+
self.register_referenced_variable(name, type_, *location, *definition_location);
86988723
}
86998724
}
87008725
}

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10329,3 +10329,46 @@ pub fn do_things(a, b) {
1032910329
find_position_of("let").select_until(find_position_of("echo x\n").under_char('\n'))
1033010330
);
1033110331
}
10332+
10333+
#[test]
10334+
fn extract_function_which_uses_variable_in_guard() {
10335+
assert_code_action!(
10336+
EXTRACT_FUNCTION,
10337+
"
10338+
pub fn do_things(a, b) {
10339+
let result = case Nil {
10340+
_ if a > b -> 17
10341+
_ if a < b -> 12
10342+
_ -> panic
10343+
}
10344+
10345+
result % 4
10346+
}
10347+
",
10348+
find_position_of("case").select_until(find_position_of("}\n").under_char('\n'))
10349+
);
10350+
}
10351+
10352+
#[test]
10353+
fn extract_function_which_uses_variable_in_bit_array_pattern() {
10354+
assert_code_action!(
10355+
EXTRACT_FUNCTION,
10356+
"
10357+
pub fn main() {
10358+
let bits = todo
10359+
let size = todo
10360+
10361+
let segment = case bits {
10362+
<<x:size(size), _:bits>> -> Ok(x)
10363+
_ -> Error(Nil)
10364+
}
10365+
10366+
case segment {
10367+
Ok(value) -> echo value
10368+
Error(_) -> panic
10369+
}
10370+
}
10371+
",
10372+
find_position_of("case").select_until(find_position_of("}\n").under_char('\n'))
10373+
);
10374+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn main() {\n let bits = todo\n let size = todo\n\n let segment = case bits {\n <<x:size(size), _:bits>> -> Ok(x)\n _ -> Error(Nil)\n }\n\n case segment {\n Ok(value) -> echo value\n Error(_) -> panic\n }\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn main() {
8+
let bits = todo
9+
let size = todo
10+
11+
let segment = case bits {
12+
▔▔▔▔▔▔▔▔▔▔▔
13+
<<x:size(size), _:bits>> -> Ok(x)
14+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
15+
_ -> Error(Nil)
16+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
17+
}
18+
▔▔▔
19+
20+
case segment {
21+
Ok(value) -> echo value
22+
Error(_) -> panic
23+
}
24+
}
25+
26+
27+
----- AFTER ACTION
28+
29+
pub fn main() {
30+
let bits = todo
31+
let size = todo
32+
33+
let segment = function(bits, size)
34+
35+
case segment {
36+
Ok(value) -> echo value
37+
Error(_) -> panic
38+
}
39+
}
40+
41+
fn function(bits: BitArray, size: Int) -> Result(Int, Nil) {
42+
case bits {
43+
<<x:size(size), _:bits>> -> Ok(x)
44+
_ -> Error(Nil)
45+
}
46+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn do_things(a, b) {\n let result = case Nil {\n _ if a > b -> 17\n _ if a < b -> 12\n _ -> panic\n }\n\n result % 4\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn do_things(a, b) {
8+
let result = case Nil {
9+
▔▔▔▔▔▔▔▔▔▔
10+
_ if a > b -> 17
11+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
12+
_ if a < b -> 12
13+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
14+
_ -> panic
15+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔
16+
}
17+
▔▔▔
18+
19+
result % 4
20+
}
21+
22+
23+
----- AFTER ACTION
24+
25+
pub fn do_things(a, b) {
26+
let result = function(a, b)
27+
28+
result % 4
29+
}
30+
31+
fn function(a: Int, b: Int) -> Int {
32+
case Nil {
33+
_ if a > b -> 17
34+
_ if a < b -> 12
35+
_ -> panic
36+
}
37+
}

0 commit comments

Comments
 (0)