compiler-cli
compiler-core
src
analyse
ast
docs
erlang
exhaustiveness
javascript
parse
type_
language-server
···
89
89
gleam_toml["dependencies"] = toml_edit::table();
90
90
}
91
91
gleam_toml["dependencies"][&added_package] = toml_edit::value(range.clone());
92
92
-
};
92
92
+
}
93
93
manifest_toml["requirements"][&added_package]["version"] = range.into();
94
94
}
95
95
}
···
90
90
},
91
91
}
92
92
93
93
-
buf.clear()
93
93
+
buf.clear();
94
94
}
95
95
96
96
// if we get here, stdout got closed before we got an "ok" or "err".
···
75
75
match perform_codegen {
76
76
Codegen::All | Codegen::DepsOnly => telemetry.compiled_package(start.elapsed()),
77
77
Codegen::None => telemetry.checked_package(start.elapsed()),
78
78
-
};
78
78
+
}
79
79
80
80
Ok(result)
81
81
}
···
69
69
70
70
if !file.try_lock_with_pid().map_err(lock_error)? {
71
71
telemetry.waiting_for_build_directory_lock();
72
72
-
file.lock_with_pid().map_err(lock_error)?
72
72
+
file.lock_with_pid().map_err(lock_error)?;
73
73
}
74
74
75
75
Ok(Guard(file))
···
42
42
}
43
43
44
44
fn downloading_package(&self, name: &str) {
45
45
-
print_downloading(name)
45
45
+
print_downloading(name);
46
46
}
47
47
48
48
fn packages_downloaded(&self, start: Instant, count: usize) {
49
49
-
print_packages_downloaded(start, count)
49
49
+
print_packages_downloaded(start, count);
50
50
}
51
51
52
52
fn resolving_package_versions(&self) {
53
53
-
print_resolving_versions()
53
53
+
print_resolving_versions();
54
54
}
55
55
56
56
fn running(&self, name: &str) {
···
58
58
}
59
59
60
60
fn waiting_for_build_directory_lock(&self) {
61
61
-
print_waiting_for_build_directory_lock()
61
61
+
print_waiting_for_build_directory_lock();
62
62
}
63
63
64
64
fn resolved_package_versions(&self, changes: &PackageChanges) {
65
65
-
print_package_changes(changes)
65
65
+
print_package_changes(changes);
66
66
}
67
67
}
68
68
···
103
103
}
104
104
105
105
pub fn print_publishing(name: &str, version: &Version) {
106
106
-
print_colourful_prefix("Publishing", &format!("{name} v{version}"))
106
106
+
print_colourful_prefix("Publishing", &format!("{name} v{version}"));
107
107
}
108
108
109
109
pub fn print_published(detail: &str) {
110
110
-
print_colourful_prefix("Published", detail)
110
110
+
print_colourful_prefix("Published", detail);
111
111
}
112
112
113
113
pub fn print_retired(package: &str, version: &str) {
114
114
-
print_colourful_prefix("Retired", &format!("{package} {version}"))
114
114
+
print_colourful_prefix("Retired", &format!("{package} {version}"));
115
115
}
116
116
117
117
pub fn print_unretired(package: &str, version: &str) {
118
118
-
print_colourful_prefix("Unretired", &format!("{package} {version}"))
118
118
+
print_colourful_prefix("Unretired", &format!("{package} {version}"));
119
119
}
120
120
121
121
pub fn print_publishing_documentation() {
···
123
123
}
124
124
125
125
fn print_downloading(text: &str) {
126
126
-
print_colourful_prefix("Downloading", text)
126
126
+
print_colourful_prefix("Downloading", text);
127
127
}
128
128
129
129
fn print_waiting_for_build_directory_lock() {
130
130
-
print_colourful_prefix("Waiting", "for build directory lock")
130
130
+
print_colourful_prefix("Waiting", "for build directory lock");
131
131
}
132
132
133
133
fn print_resolving_versions() {
134
134
-
print_colourful_prefix("Resolving", "versions")
134
134
+
print_colourful_prefix("Resolving", "versions");
135
135
}
136
136
137
137
fn print_compiling(text: &str) {
138
138
-
print_colourful_prefix("Compiling", text)
138
138
+
print_colourful_prefix("Compiling", text);
139
139
}
140
140
141
141
pub(crate) fn print_exported(text: &str) {
142
142
-
print_colourful_prefix("Exported", text)
142
142
+
print_colourful_prefix("Exported", text);
143
143
}
144
144
145
145
pub(crate) fn print_checking(text: &str) {
146
146
-
print_colourful_prefix("Checking", text)
146
146
+
print_colourful_prefix("Checking", text);
147
147
}
148
148
149
149
pub(crate) fn print_compiled(duration: Duration) {
150
150
-
print_colourful_prefix("Compiled", &format!("in {}", seconds(duration)))
150
150
+
print_colourful_prefix("Compiled", &format!("in {}", seconds(duration)));
151
151
}
152
152
153
153
pub(crate) fn print_checked(duration: Duration) {
154
154
-
print_colourful_prefix("Checked", &format!("in {}", seconds(duration)))
154
154
+
print_colourful_prefix("Checked", &format!("in {}", seconds(duration)));
155
155
}
156
156
157
157
pub(crate) fn print_running(text: &str) {
158
158
-
print_colourful_prefix("Running", text)
158
158
+
print_colourful_prefix("Running", text);
159
159
}
160
160
161
161
pub(crate) fn print_package_changes(changes: &PackageChanges) {
···
179
179
}
180
180
181
181
fn print_added(text: &str) {
182
182
-
print_colourful_prefix("Added", text)
182
182
+
print_colourful_prefix("Added", text);
183
183
}
184
184
185
185
fn print_changed(text: &str) {
186
186
-
print_colourful_prefix("Changed", text)
186
186
+
print_colourful_prefix("Changed", text);
187
187
}
188
188
189
189
fn print_removed(text: &str) {
190
190
-
print_colourful_prefix("Removed", text)
190
190
+
print_colourful_prefix("Removed", text);
191
191
}
192
192
193
193
pub(crate) fn print_generating_documentation() {
194
194
-
print_colourful_prefix("Generating", "documentation")
194
194
+
print_colourful_prefix("Generating", "documentation");
195
195
}
196
196
197
197
pub(crate) fn print_transferring_ownership() {
···
216
216
1 => format!("1 package in {elapsed}"),
217
217
_ => format!("{count} packages in {elapsed}"),
218
218
};
219
219
-
print_colourful_prefix("Downloaded", &msg)
219
219
+
print_colourful_prefix("Downloaded", &msg);
220
220
}
221
221
222
222
pub fn seconds(duration: Duration) -> String {
···
831
831
if config_time <= fingerprint_time {
832
832
continue;
833
833
}
834
834
-
};
834
834
+
}
835
835
836
836
let config_text = fs::read(&config_path)?;
837
837
let current_fingerprint = SourceFingerprint::new(&config_text).to_numerical_string();
···
1512
1512
path: package_path.to_path_buf(),
1513
1513
found: config.name.into(),
1514
1514
});
1515
1515
-
};
1515
1515
+
}
1516
1516
// Walk the requirements of the package
1517
1517
let mut requirements = HashMap::new();
1518
1518
parents.push(package_name);
···
160
160
loop {
161
161
let password = cli::ask_password(LOCAL_PASS_PROMPT)?;
162
162
if password.chars().count() < required_length {
163
163
-
println!("\nPlease use a password at least {required_length} characters long.\n")
163
163
+
println!("\nPlease use a password at least {required_length} characters long.\n");
164
164
} else {
165
165
self.local_password = Some(password);
166
166
return Ok(());
···
6
6
7
7
pub fn add_handler() {
8
8
std::panic::set_hook(Box::new(move |info: &PanicHookInfo<'_>| {
9
9
-
print_compiler_bug_message(info)
9
9
+
print_compiler_bug_message(info);
10
10
}));
11
11
}
12
12
···
66
66
return Err(Error::InvalidModuleName {
67
67
module: mod_path.to_owned(),
68
68
});
69
69
-
};
69
69
+
}
70
70
71
71
let telemetry: &'static dyn Telemetry = if no_print_progress {
72
72
&NullTelemetry
···
280
280
281
281
// Enable unstable features and APIs
282
282
if config.javascript.deno.unstable {
283
283
-
args.push("--unstable".into())
283
283
+
args.push("--unstable".into());
284
284
}
285
285
286
286
// Enable location API
···
291
291
// Set deno permissions
292
292
if config.javascript.deno.allow_all {
293
293
// Allow all
294
294
-
args.push("--allow-all".into())
294
294
+
args.push("--allow-all".into());
295
295
} else {
296
296
// Allow env
297
297
add_deno_flag(&mut args, "--allow-env", &config.javascript.deno.allow_env);
298
298
299
299
// Allow sys
300
300
if config.javascript.deno.allow_sys {
301
301
-
args.push("--allow-sys".into())
301
301
+
args.push("--allow-sys".into());
302
302
}
303
303
304
304
// Allow hrtime
305
305
if config.javascript.deno.allow_hrtime {
306
306
-
args.push("--allow-hrtime".into())
306
306
+
args.push("--allow-hrtime".into());
307
307
}
308
308
309
309
// Allow net
···
311
311
312
312
// Allow ffi
313
313
if config.javascript.deno.allow_ffi {
314
314
-
args.push("--allow-ffi".into())
314
314
+
args.push("--allow-ffi".into());
315
315
}
316
316
317
317
// Allow read
···
305
305
for definition in group {
306
306
match definition {
307
307
CallGraphNode::Function(function) => {
308
308
-
working_functions.push(self.infer_function(function, &mut env))
308
308
+
working_functions.push(self.infer_function(function, &mut env));
309
309
}
310
310
CallGraphNode::ModuleConstant(constant) => {
311
311
-
working_constants.push(self.infer_module_constant(constant, &mut env))
311
311
+
working_constants.push(self.infer_module_constant(constant, &mut env));
312
312
}
313
313
-
};
313
313
+
}
314
314
}
315
315
316
316
// Now that the entire group has been inferred, generalise their types.
···
319
319
inferred_constant,
320
320
&mut env,
321
321
&self.module_name,
322
322
-
))
322
322
+
));
323
323
}
324
324
for inferred_function in working_functions.drain(..) {
325
325
typed_functions.push(generalise_function(
···
350
350
351
351
// Ensure no exported values have private types in their type signature
352
352
for value in env.module_values.values() {
353
353
-
self.check_for_type_leaks(value)
353
353
+
self.check_for_type_leaks(value);
354
354
}
355
355
356
356
// Resolve deferred type variable aliases now that all unification is
···
753
753
if let Some((module, _, location)) = &external_javascript
754
754
&& module.contains('@')
755
755
{
756
756
-
self.track_feature_usage(FeatureKind::AtInJavascriptModules, *location)
756
756
+
self.track_feature_usage(FeatureKind::AtInJavascriptModules, *location);
757
757
}
758
758
759
759
// Assert that the inferred type matches the type of any recursive call
···
953
953
location,
954
954
module: module_info.name.clone(),
955
955
package: module_info.package.clone(),
956
956
-
})
956
956
+
});
957
957
}
958
958
959
959
Some(Import {
···
1729
1729
feature_kind,
1730
1730
minimum_required_version: minimum_required_version.clone(),
1731
1731
wrongfully_allowed_version: lowest_allowed_version,
1732
1732
-
})
1732
1732
+
});
1733
1733
}
1734
1734
}
1735
1735
···
1757
1757
fn validate_module_name(name: &EcoString) -> Result<(), Error> {
1758
1758
if is_prelude_module(name) {
1759
1759
return Err(Error::ReservedModuleName { name: name.clone() });
1760
1760
-
};
1760
1760
+
}
1761
1761
for segment in name.split('/') {
1762
1762
if crate::parse::lexer::string_to_keyword(segment).is_some() {
1763
1763
return Err(Error::KeywordInModuleName {
···
2151
2151
label: first_label.clone(),
2152
2152
type_: first_parameter.type_.clone(),
2153
2153
documentation,
2154
2154
-
})
2154
2154
+
});
2155
2155
}
2156
2156
2157
2157
compatible
···
2180
2180
});
2181
2181
2182
2182
for arg in arguments {
2183
2183
-
deps.extend(get_type_dependencies(arg))
2183
2183
+
deps.extend(get_type_dependencies(arg));
2184
2184
}
2185
2185
}
2186
2186
TypeAst::Fn(TypeAstFn {
2187
2187
arguments, return_, ..
2188
2188
}) => {
2189
2189
for arg in arguments {
2190
2190
-
deps.extend(get_type_dependencies(arg))
2190
2190
+
deps.extend(get_type_dependencies(arg));
2191
2191
}
2192
2192
-
deps.extend(get_type_dependencies(return_))
2192
2192
+
deps.extend(get_type_dependencies(return_));
2193
2193
}
2194
2194
TypeAst::Tuple(TypeAstTuple { elements, .. }) => {
2195
2195
for element in elements {
2196
2196
-
deps.extend(get_type_dependencies(element))
2196
2196
+
deps.extend(get_type_dependencies(element));
2197
2197
}
2198
2198
}
2199
2199
}
···
2205
2205
let mut deps: Vec<(EcoString, Vec<EcoString>)> = Vec::with_capacity(aliases.len());
2206
2206
2207
2207
for alias in aliases {
2208
2208
-
deps.push((alias.alias.clone(), get_type_dependencies(&alias.type_ast)))
2208
2208
+
deps.push((alias.alias.clone(), get_type_dependencies(&alias.type_ast)));
2209
2209
}
2210
2210
2211
2211
let sorted_deps = dep_tree::toposort_deps(deps).map_err(|err| {
···
43
43
) -> Environment<'context> {
44
44
let mut importer = Self::new(origin, env, problems);
45
45
for import in imports {
46
46
-
importer.register_import(import)
46
46
+
importer.register_import(import);
47
47
}
48
48
importer.environment
49
49
}
···
161
161
self.problems.error(Error::UnsupportedExpressionTarget {
162
162
target: self.environment.target,
163
163
location,
164
164
-
})
164
164
+
});
165
165
}
166
166
167
167
self.environment.insert_variable(
···
240
240
);
241
241
}
242
242
ValueConstructorVariant::LocalVariable { .. } => {}
243
243
-
};
243
243
+
}
244
244
245
245
// Check if value already was imported
246
246
if let Some(previous) = self.environment.unqualified_imported_names.get(used_name) {
···
659
659
buffer.push_str(", ");
660
660
}
661
661
}
662
662
-
buffer.push(')')
662
662
+
buffer.push(')');
663
663
}
664
664
TypeAst::Fn(func) => {
665
665
buffer.push_str("fn(");
···
683
683
buffer.push_str(name);
684
684
}
685
685
}
686
686
-
};
686
686
+
}
687
687
688
688
if !constructor.arguments.is_empty() {
689
689
buffer.push('(');
···
905
905
.find_map(|arg| arg.find_node(byte_index))
906
906
{
907
907
return Some(found_arg);
908
908
-
};
908
908
+
}
909
909
910
910
if let Some(found_statement) = self
911
911
.body
···
913
913
.find(|statement| statement.location().contains(byte_index))
914
914
{
915
915
return Some(Located::Statement(found_statement));
916
916
-
};
916
916
+
}
917
917
918
918
// Check if location is within the return annotation.
919
919
if let Some(located) = self
···
922
922
.find_map(|annotation| annotation.find_node(byte_index, self.return_type.clone()))
923
923
{
924
924
return Some(located);
925
925
-
};
925
925
+
}
926
926
927
927
// Note that the fn `.location` covers the function head, not
928
928
// the entire statement.
···
3643
3643
},
3644
3644
location,
3645
3645
type_: type_.clone(),
3646
3646
-
})
3647
3647
-
};
3646
3646
+
});
3647
3647
+
}
3648
3648
}
3649
3649
Pattern::Constructor { arguments, .. } => {
3650
3650
for argument in arguments {
···
3653
3653
name: BoundVariableName::ShorthandLabel { name: name.clone() },
3654
3654
location: argument.location,
3655
3655
type_: argument.value.type_(),
3656
3656
-
})
3656
3656
+
});
3657
3657
} else {
3658
3658
argument.value.collect_bound_variables(variables);
3659
3659
}
···
4402
4402
let mut this = Self::default();
4403
4403
4404
4404
for definition in definitions {
4405
4405
-
this.add(definition)
4405
4405
+
this.add(definition);
4406
4406
}
4407
4407
4408
4408
this
···
1810
1810
let Some(label) = argument.label.as_ref() else {
1811
1811
continue;
1812
1812
};
1813
1813
-
unchanged_arguments.push((label.clone(), argument.value.type_()))
1813
1813
+
unchanged_arguments.push((label.clone(), argument.value.type_()));
1814
1814
}
1815
1815
Some(unchanged_arguments)
1816
1816
}
···
89
89
}
90
90
91
91
fn visit_typed_type_alias(&mut self, type_alias: &'ast TypedTypeAlias) {
92
92
-
visit_typed_type_alias(self, type_alias)
92
92
+
visit_typed_type_alias(self, type_alias);
93
93
}
94
94
95
95
fn visit_typed_import(&mut self, import: &'ast TypedImport) {
96
96
-
visit_typed_import(self, import)
96
96
+
visit_typed_import(self, import);
97
97
}
98
98
99
99
fn visit_typed_expr(&mut self, expr: &'ast TypedExpr) {
···
357
357
}
358
358
359
359
fn visit_typed_expr_negate_int(&mut self, location: &'ast SrcSpan, value: &'ast TypedExpr) {
360
360
-
visit_typed_expr_negate_int(self, location, value)
360
360
+
visit_typed_expr_negate_int(self, location, value);
361
361
}
362
362
363
363
fn visit_typed_expr_invalid(
···
430
430
type_: &'ast Arc<Type>,
431
431
tuple: &'ast TypedClauseGuard,
432
432
) {
433
433
-
visit_typed_clause_guard_tuple_index(self, location, index, type_, tuple)
433
433
+
visit_typed_clause_guard_tuple_index(self, location, index, type_, tuple);
434
434
}
435
435
436
436
fn visit_typed_clause_guard_field_access(
···
441
441
type_: &'ast Arc<Type>,
442
442
container: &'ast TypedClauseGuard,
443
443
) {
444
444
-
visit_typed_clause_guard_field_access(self, label_location, index, label, type_, container)
444
444
+
visit_typed_clause_guard_field_access(self, label_location, index, label, type_, container);
445
445
}
446
446
447
447
#[allow(clippy::too_many_arguments)]
···
466
466
module_name,
467
467
module_alias,
468
468
literal,
469
469
-
)
469
469
+
);
470
470
}
471
471
472
472
fn visit_typed_expr_bit_array_segment(&mut self, segment: &'ast TypedExprBitArraySegment) {
···
508
508
}
509
509
510
510
fn visit_typed_bit_array_size_int(&mut self, location: &'ast SrcSpan, value: &'ast EcoString) {
511
511
-
visit_typed_bit_array_size_int(self, location, value)
511
511
+
visit_typed_bit_array_size_int(self, location, value);
512
512
}
513
513
514
514
fn visit_typed_bit_array_size_variable(
···
518
518
constructor: &'ast Option<Box<ValueConstructor>>,
519
519
type_: &'ast Arc<Type>,
520
520
) {
521
521
-
visit_typed_bit_array_size_variable(self, location, name, constructor, type_)
521
521
+
visit_typed_bit_array_size_variable(self, location, name, constructor, type_);
522
522
}
523
523
524
524
fn visit_typed_pattern_assign(
···
536
536
name: &'ast EcoString,
537
537
type_: &'ast Arc<Type>,
538
538
) {
539
539
-
visit_typed_pattern_discard(self, location, name, type_)
539
539
+
visit_typed_pattern_discard(self, location, name, type_);
540
540
}
541
541
542
542
fn visit_typed_pattern_list(
···
757
757
type_,
758
758
field_map,
759
759
record_constructor,
760
760
-
)
760
760
+
);
761
761
}
762
762
763
763
#[allow(clippy::too_many_arguments)]
···
782
782
arguments,
783
783
type_,
784
784
field_map,
785
785
-
)
785
785
+
);
786
786
}
787
787
788
788
fn visit_typed_constant_bit_array(
···
873
873
_record_constructor: &'a Option<Box<ValueConstructor>>,
874
874
) {
875
875
for argument in arguments.iter().flatten() {
876
876
-
v.visit_typed_constant(&argument.value)
876
876
+
v.visit_typed_constant(&argument.value);
877
877
}
878
878
}
879
879
···
903
903
tail: &'a Option<Box<TypedConstant>>,
904
904
) {
905
905
for element in elements {
906
906
-
v.visit_typed_constant(element)
906
906
+
v.visit_typed_constant(element);
907
907
}
908
908
if let Some(tail) = tail {
909
909
v.visit_typed_constant(tail);
···
917
917
_type_: &'a Arc<Type>,
918
918
) {
919
919
for element in elements {
920
920
-
v.visit_typed_constant(element)
920
920
+
v.visit_typed_constant(element);
921
921
}
922
922
}
923
923
···
1156
1156
float_value,
1157
1157
} => v.visit_typed_constant_float(location, value, float_value),
1158
1158
super::Constant::String { location, value } => {
1159
1159
-
v.visit_typed_constant_string(location, value)
1159
1159
+
v.visit_typed_constant_string(location, value);
1160
1160
}
1161
1161
super::Constant::Tuple {
1162
1162
location,
···
1206
1206
field_map,
1207
1207
),
1208
1208
super::Constant::BitArray { location, segments } => {
1209
1209
-
v.visit_typed_constant_bit_array(location, segments)
1209
1209
+
v.visit_typed_constant_bit_array(location, segments);
1210
1210
}
1211
1211
super::Constant::Var {
1212
1212
location,
···
1406
1406
arguments,
1407
1407
),
1408
1408
TypedExpr::NegateBool { location, value } => {
1409
1409
-
v.visit_typed_expr_negate_bool(location, value)
1409
1409
+
v.visit_typed_expr_negate_bool(location, value);
1410
1410
}
1411
1411
TypedExpr::NegateInt { location, value } => v.visit_typed_expr_negate_int(location, value),
1412
1412
TypedExpr::Invalid {
···
1676
1676
V: Visit<'a> + ?Sized,
1677
1677
{
1678
1678
if let Some(expression) = expression {
1679
1679
-
v.visit_typed_expr(expression)
1679
1679
+
v.visit_typed_expr(expression);
1680
1680
}
1681
1681
if let Some(message) = message {
1682
1682
-
v.visit_typed_expr(message)
1682
1682
+
v.visit_typed_expr(message);
1683
1683
}
1684
1684
}
1685
1685
···
1846
1846
type_,
1847
1847
container,
1848
1848
} => {
1849
1849
-
v.visit_typed_clause_guard_field_access(label_location, index, label, type_, container)
1849
1849
+
v.visit_typed_clause_guard_field_access(label_location, index, label, type_, container);
1850
1850
}
1851
1851
super::ClauseGuard::ModuleSelect {
1852
1852
location,
···
2043
2043
),
2044
2044
Pattern::Tuple { location, elements } => v.visit_typed_pattern_tuple(location, elements),
2045
2045
Pattern::BitArray { location, segments } => {
2046
2046
-
v.visit_typed_pattern_bit_array(location, segments)
2046
2046
+
v.visit_typed_pattern_bit_array(location, segments);
2047
2047
}
2048
2048
Pattern::StringPrefix {
2049
2049
location,
···
2198
2198
where
2199
2199
V: Visit<'a> + ?Sized,
2200
2200
{
2201
2201
-
v.visit_typed_pattern(&argument.value)
2201
2201
+
v.visit_typed_pattern(&argument.value);
2202
2202
}
2203
2203
2204
2204
pub fn visit_typed_pattern_tuple<'a, V>(
···
173
173
Statement::Assert(assert) => {
174
174
self.expression(&assert.value);
175
175
if let Some(message) = &assert.message {
176
176
-
self.expression(message)
176
176
+
self.expression(message);
177
177
}
178
178
}
179
179
-
};
179
179
+
}
180
180
}
181
181
182
182
fn expression(&mut self, expression: &'a UntypedExpr) {
···
185
185
186
186
UntypedExpr::Todo { message, .. } => {
187
187
if let Some(msg_expr) = message {
188
188
-
self.expression(msg_expr)
188
188
+
self.expression(msg_expr);
189
189
}
190
190
}
191
191
192
192
UntypedExpr::Panic { message, .. } => {
193
193
if let Some(msg_expr) = message {
194
194
-
self.expression(msg_expr)
194
194
+
self.expression(msg_expr);
195
195
}
196
196
}
197
197
···
295
295
let names = self.names.clone();
296
296
for argument in arguments {
297
297
if let Some(name) = argument.names.get_variable_name() {
298
298
-
self.define(name)
298
298
+
self.define(name);
299
299
}
300
300
}
301
301
self.statements(body);
···
468
468
469
469
Constant::Todo { message, .. } => {
470
470
if let Some(message) = message {
471
471
-
self.constant(message)
471
471
+
self.constant(message);
472
472
}
473
473
}
474
474
···
213
213
if self.typescript == TypeScriptDeclarations::Emit {
214
214
self.ts_declaration(writer, module, &js_name)?;
215
215
}
216
216
-
self.js_module(writer, module, &js_name, stdlib_package)?
216
216
+
self.js_module(writer, module, &js_name, stdlib_package)?;
217
217
}
218
218
self.write_prelude(writer)?;
219
219
Ok(())
···
338
338
package_range.union(other_package_range),
339
339
required_package.clone(),
340
340
required_package_range.union(other_required_package_range),
341
341
-
))
341
341
+
));
342
342
}
343
343
344
344
_ => {}
···
68
68
match &self.location {
69
69
Some(location) => self.write_span(location, buffer),
70
70
None => self.write_title(buffer),
71
71
-
};
71
71
+
}
72
72
73
73
if !self.text.is_empty() {
74
74
writeln!(buffer, "{}", self.text).expect("write text");
···
154
154
},
155
155
source_url: source_links.url(*location),
156
156
opaque: *opaque,
157
157
-
})
157
157
+
});
158
158
}
159
159
160
160
for TypeAlias {
···
190
190
Deprecation::Deprecated { message } => message.to_string(),
191
191
},
192
192
opaque: false,
193
193
-
})
193
193
+
});
194
194
}
195
195
196
196
type_definitions.sort();
···
256
256
Deprecation::NotDeprecated => "".to_string(),
257
257
Deprecation::Deprecated { message } => message.to_string(),
258
258
},
259
259
-
})
259
259
+
});
260
260
}
261
261
262
262
for TypedModuleConstant {
···
284
284
Deprecation::NotDeprecated => "".to_string(),
285
285
Deprecation::Deprecated { message } => message.to_string(),
286
286
},
287
287
-
})
287
287
+
});
288
288
}
289
289
290
290
value_definitions.sort();
···
627
627
if rest == 0 {
628
628
break;
629
629
}
630
630
-
rest -= 1
630
630
+
rest -= 1;
631
631
}
632
632
633
633
self.next_type_variable_id += 1;
···
273
273
let documentation = &self.module.documentation.iter().join("\n");
274
274
builder.string(documentation);
275
275
builder.end_doc_attribute(doc);
276
276
-
};
276
276
+
}
277
277
}
278
278
279
279
fn type_definition<Output>(
···
672
672
let spec = builder.start_function_spec(function_name, function.arguments.len());
673
673
let function_type = builder.start_function_type();
674
674
for argument in &function.arguments {
675
675
-
generator.type_(builder, &argument.type_)
675
675
+
generator.type_(builder, &argument.type_);
676
676
}
677
677
let function_type = builder.end_function_type_arguments(function_type);
678
678
generator.type_(builder, &function.return_type);
···
769
769
Statement::Assert(assert) => self.assert(builder, assert),
770
770
Statement::Assignment(assignment) => match &assignment.kind {
771
771
AssignmentKind::Let | AssignmentKind::Generated => {
772
772
-
self.let_(builder, &assignment.value, &assignment.pattern)
772
772
+
self.let_(builder, &assignment.value, &assignment.pattern);
773
773
}
774
774
// Let asserts are slightly different from everything else:
775
775
// A let assert is compiled to a case expression where we
···
838
838
} else {
839
839
let block = builder.start_block();
840
840
self.statement_sequence(builder, statements);
841
841
-
builder.end_block(block)
841
841
+
builder.end_block(block);
842
842
}
843
843
}
844
844
···
847
847
//
848
848
TypedExpr::NegateBool { value, .. } => {
849
849
builder.unary_operator("not");
850
850
-
self.maybe_block_expr(builder, value)
850
850
+
self.maybe_block_expr(builder, value);
851
851
}
852
852
TypedExpr::NegateInt { value, .. } => {
853
853
builder.unary_operator("-");
854
854
-
self.maybe_block_expr(builder, value)
854
854
+
self.maybe_block_expr(builder, value);
855
855
}
856
856
TypedExpr::BinOp {
857
857
operator,
···
889
889
for element in elements {
890
890
self.maybe_block_expr(builder, element);
891
891
}
892
892
-
builder.end_tuple(tuple)
892
892
+
builder.end_tuple(tuple);
893
893
}
894
894
895
895
//
···
899
899
TypedExpr::TupleIndex { tuple, index, .. } => self.tuple_index(builder, tuple, *index),
900
900
TypedExpr::RecordAccess { record, index, .. }
901
901
| TypedExpr::PositionalAccess { record, index, .. } => {
902
902
-
self.tuple_index(builder, record, index + 1)
902
902
+
self.tuple_index(builder, record, index + 1);
903
903
}
904
904
905
905
//
···
926
926
self.maybe_block_expr(builder, updated_record);
927
927
}
928
928
// Then a record update is simply a call!
929
929
-
self.call(builder, constructor, arguments)
929
929
+
self.call(builder, constructor, arguments);
930
930
}
931
931
932
932
//
···
1066
1066
if let Some(message) = message {
1067
1067
self.maybe_block_expr(builder, message);
1068
1068
} else {
1069
1069
-
builder.atom("nil")
1069
1069
+
builder.atom("nil");
1070
1070
}
1071
1071
1072
1072
// ...the filepath of this module...
···
1115
1115
if let Some(message) = message {
1116
1116
self.maybe_block_expr(builder, message);
1117
1117
} else {
1118
1118
-
builder.string(error_kind.default_error_message())
1118
1118
+
builder.string(error_kind.default_error_message());
1119
1119
}
1120
1120
1121
1121
builder.map_field();
···
1177
1177
) {
1178
1178
builder.match_operator();
1179
1179
PatternGenerator::new(self).pattern(builder, pattern);
1180
1180
-
self.maybe_block_expr(builder, value)
1180
1180
+
self.maybe_block_expr(builder, value);
1181
1181
}
1182
1182
1183
1183
fn let_assert<Output>(
···
1328
1328
.to_owned()
1329
1329
.expect("echo with no previous step in a pipe"),
1330
1330
},
1331
1331
-
)
1331
1331
+
);
1332
1332
} else {
1333
1333
self.maybe_block_expr(builder, &assignment.value);
1334
1334
previous_step_variable_name = Some(name);
1335
1335
-
};
1335
1335
+
}
1336
1336
}
1337
1337
1338
1338
// We also need to do the same thing for the final step of the pipeline.
···
1353
1353
name: previous_step_variable_name
1354
1354
.expect("echo with no previous step in a pipe"),
1355
1355
},
1356
1356
-
)
1356
1356
+
);
1357
1357
} else {
1358
1358
-
self.expression(builder, finally)
1358
1358
+
self.expression(builder, finally);
1359
1359
}
1360
1360
}
1361
1361
···
1893
1893
AssertedExpressionRuntimeValue::KnownBool(false) => builder.atom("false"),
1894
1894
AssertedExpressionRuntimeValue::Variable(name) => builder.variable(name),
1895
1895
AssertedExpressionRuntimeValue::Expression(expr) => {
1896
1896
-
self.maybe_block_expr(builder, expr)
1896
1896
+
self.maybe_block_expr(builder, expr);
1897
1897
}
1898
1898
}
1899
1899
}
···
1938
1938
// }
1939
1939
// ```
1940
1940
Type::Named { .. } | Type::Var { .. } | Type::Tuple { .. } => {
1941
1941
-
builder.atom(&to_snake_case(record_name))
1941
1941
+
builder.atom(&to_snake_case(record_name));
1942
1942
}
1943
1943
Type::Fn { arguments, .. } => {
1944
1944
-
self.record_builder_anonymous_function(builder, record_name, arguments.len())
1944
1944
+
self.record_builder_anonymous_function(builder, record_name, arguments.len());
1945
1945
}
1946
1946
},
1947
1947
1948
1948
ValueConstructorVariant::LocalVariable { location, .. } => {
1949
1949
-
builder.variable(&self.local_var_name(location))
1949
1949
+
builder.variable(&self.local_var_name(location));
1950
1950
}
1951
1951
1952
1952
ValueConstructorVariant::ModuleConstant { literal, .. } => {
1953
1953
-
self.inlined_constant(builder, literal)
1953
1953
+
self.inlined_constant(builder, literal);
1954
1954
}
1955
1955
1956
1956
ValueConstructorVariant::ModuleFn {
···
1960
1960
} => {
1961
1961
let name = escape_erlang_existing_name(name);
1962
1962
if *module == self.module_generator.module.name {
1963
1963
-
builder.function_reference(None, name, *arity)
1963
1963
+
builder.function_reference(None, name, *arity);
1964
1964
} else {
1965
1965
-
builder.function_reference(Some(ErlangModuleName::new(module)), name, *arity)
1965
1965
+
builder.function_reference(Some(ErlangModuleName::new(module)), name, *arity);
1966
1966
}
1967
1967
}
1968
1968
1969
1969
ValueConstructorVariant::ModuleFn { arity, module, .. }
1970
1970
if *module == self.module_generator.module.name =>
1971
1971
{
1972
1972
-
builder.function_reference(None, escape_erlang_existing_name(name), *arity)
1972
1972
+
builder.function_reference(None, escape_erlang_existing_name(name), *arity);
1973
1973
}
1974
1974
1975
1975
ValueConstructorVariant::ModuleFn {
···
2012
2012
for argument in arguments {
2013
2013
self.maybe_block_expr(builder, &argument.value);
2014
2014
}
2015
2015
-
builder.end_call(call)
2015
2015
+
builder.end_call(call);
2016
2016
}
2017
2017
// If we're calling anything else (like an anonymous function, or
2018
2018
// the result of another function call) we generate its code and
···
2067
2067
for argument in arguments {
2068
2068
self.runtime_value(builder, argument);
2069
2069
}
2070
2070
-
builder.end_call(call)
2070
2070
+
builder.end_call(call);
2071
2071
}
2072
2072
2073
2073
// If we're calling anything else (like an anonymous function, or
···
2098
2098
arguments: &'a [TypedCallArg],
2099
2099
) {
2100
2100
if arguments.is_empty() {
2101
2101
-
builder.atom(&to_snake_case(record_name))
2101
2101
+
builder.atom(&to_snake_case(record_name));
2102
2102
} else {
2103
2103
let tuple = builder.start_tuple();
2104
2104
builder.atom(&to_snake_case(record_name));
2105
2105
for argument in arguments {
2106
2106
self.maybe_block_expr(builder, &argument.value);
2107
2107
}
2108
2108
-
builder.end_tuple(tuple)
2108
2108
+
builder.end_tuple(tuple);
2109
2109
}
2110
2110
}
2111
2111
···
2195
2195
}
2196
2196
builder.end_tuple_pattern(tuple);
2197
2197
}
2198
2198
-
};
2198
2198
+
}
2199
2199
2200
2200
let variables_to_add_later = pattern_generator.variables_to_add_later;
2201
2201
···
2245
2245
Constant::Tuple { elements, .. } => {
2246
2246
let tuple = builder.start_tuple();
2247
2247
for element in elements {
2248
2248
-
self.inlined_constant(builder, element)
2248
2248
+
self.inlined_constant(builder, element);
2249
2249
}
2250
2250
builder.end_tuple(tuple);
2251
2251
}
···
2253
2253
Constant::List { elements, tail, .. } => {
2254
2254
for element in elements {
2255
2255
builder.cons_list();
2256
2256
-
self.inlined_constant(builder, element)
2256
2256
+
self.inlined_constant(builder, element);
2257
2257
}
2258
2258
match tail {
2259
2259
// If there's no tail we simply add an empty list cell to
···
2319
2319
// ```
2320
2320
None => match type_::collapse_links(type_.clone()).deref() {
2321
2321
Type::Named { .. } | Type::Var { .. } | Type::Tuple { .. } => {
2322
2322
-
builder.atom(&to_snake_case(&tag))
2322
2322
+
builder.atom(&to_snake_case(&tag));
2323
2323
}
2324
2324
Type::Fn { arguments, .. } => {
2325
2325
-
self.record_builder_anonymous_function(builder, &tag, arguments.len())
2325
2325
+
self.record_builder_anonymous_function(builder, &tag, arguments.len());
2326
2326
}
2327
2327
},
2328
2328
}
2329
2329
}
2330
2330
2331
2331
Constant::StringConcatenation { left, right, .. } => {
2332
2332
-
self.constant_string_concatenate(builder, left, right)
2332
2332
+
self.constant_string_concatenate(builder, left, right);
2333
2333
}
2334
2334
2335
2335
Constant::RecordUpdate { .. } => {
···
2351
2351
self.inlined_constant(builder, &segment.value);
2352
2352
match segment.size() {
2353
2353
Some(TypedConstant::Int { int_value, .. }) if int_value.is_negative() => {
2354
2354
-
builder.int(BigInt::ZERO)
2354
2354
+
builder.int(BigInt::ZERO);
2355
2355
}
2356
2356
Some(size) => self.inlined_constant(builder, size),
2357
2357
None => builder.atom("default"),
2358
2358
-
};
2358
2358
+
}
2359
2359
self.bit_array_segment_specifiers(builder, segment);
2360
2360
}
2361
2361
···
2809
2809
// negative value must be turned to zero instead:
2810
2810
if let TypedExpr::Int { int_value, .. } = &size {
2811
2811
if int_value.is_negative() {
2812
2812
-
builder.int(BigInt::ZERO)
2812
2812
+
builder.int(BigInt::ZERO);
2813
2813
} else {
2814
2814
builder.int(int_value.clone());
2815
2815
}
···
2836
2836
ClauseGuard::Block { value, .. } => self.clause_guard(builder, value, assignments),
2837
2837
2838
2838
ClauseGuard::TupleIndex { tuple, index, .. } => {
2839
2839
-
self.clause_guard_tuple_index(builder, tuple, *index)
2839
2839
+
self.clause_guard_tuple_index(builder, tuple, *index);
2840
2840
}
2841
2841
2842
2842
ClauseGuard::FieldAccess {
···
2994
2994
let function = builder.start_anonymous_function(&arguments);
2995
2995
2996
2996
if arguments.is_empty() {
2997
2997
-
builder.atom(&to_snake_case(record_name))
2997
2997
+
builder.atom(&to_snake_case(record_name));
2998
2998
} else {
2999
2999
let tuple = builder.start_tuple();
3000
3000
builder.atom(&to_snake_case(record_name));
3001
3001
for argument in arguments {
3002
3002
builder.variable(&argument);
3003
3003
}
3004
3004
-
builder.end_tuple(tuple)
3004
3004
+
builder.end_tuple(tuple);
3005
3005
}
3006
3006
3007
3007
builder.end_function(function);
···
3761
3761
..
3762
3762
} => match arguments[..] {
3763
3763
[ref arg_ok, ref arg_err] if is_prelude_module(module) && name == "Result" => {
3764
3764
-
result_type_var_ids(ids, arg_ok, arg_err)
3764
3764
+
result_type_var_ids(ids, arg_ok, arg_err);
3765
3765
}
3766
3766
_ => {
3767
3767
for argument in arguments {
3768
3768
-
type_var_ids(argument, ids)
3768
3768
+
type_var_ids(argument, ids);
3769
3769
}
3770
3770
}
3771
3771
},
3772
3772
Type::Fn { arguments, return_ } => {
3773
3773
for argument in arguments {
3774
3774
-
type_var_ids(argument, ids)
3774
3774
+
type_var_ids(argument, ids);
3775
3775
}
3776
3776
type_var_ids(return_, ids);
3777
3777
}
3778
3778
Type::Tuple { elements } => {
3779
3779
for element in elements {
3780
3780
-
type_var_ids(element, ids)
3780
3780
+
type_var_ids(element, ids);
3781
3781
}
3782
3782
}
3783
3783
}
···
3908
3908
Type::Tuple { elements } => {
3909
3909
let tuple = builder.start_tuple_type();
3910
3910
for element in elements {
3911
3911
-
self.type_(builder, element)
3911
3911
+
self.type_(builder, element);
3912
3912
}
3913
3913
builder.end_tuple_type(tuple);
3914
3914
}
···
3923
3923
let any = builder.start_named_type("any");
3924
3924
builder.end_named_type(any);
3925
3925
} else {
3926
3926
-
builder.type_variable(&id_to_type_var_str(*id))
3926
3926
+
builder.type_variable(&id_to_type_var_str(*id));
3927
3927
}
3928
3928
}
3929
3929
}
···
4017
4017
};
4018
4018
4019
4019
for argument in arguments {
4020
4020
-
self.type_(builder, argument)
4020
4020
+
self.type_(builder, argument);
4021
4021
}
4022
4022
4023
4023
builder.end_named_type(type_);
···
4031
4031
4032
4032
for constant in &module.definitions.constants {
4033
4033
if constant.publicity.is_importable() {
4034
4034
-
find_referenced_private_functions(&constant.value, &mut overridden_publicity)
4034
4034
+
find_referenced_private_functions(&constant.value, &mut overridden_publicity);
4035
4035
}
4036
4036
}
4037
4037
overridden_publicity
···
138
138
Pattern::Int { int_value, .. } => builder.int_pattern(int_value.clone()),
139
139
Pattern::String { value, .. } => builder.string_pattern(value),
140
140
Pattern::Variable { name, location, .. } => {
141
141
-
builder.variable_pattern(&self.generator.new_erlang_variable(name, *location))
141
141
+
builder.variable_pattern(&self.generator.new_erlang_variable(name, *location));
142
142
}
143
143
144
144
Pattern::Assign {
···
272
272
let constructor = constructor.as_ref().expect("variable with no constructor");
273
273
match &constructor.variant {
274
274
ValueConstructorVariant::ModuleConstant { literal, .. } => {
275
275
-
self.generator.inlined_constant(builder, literal)
275
275
+
self.generator.inlined_constant(builder, literal);
276
276
}
277
277
ValueConstructorVariant::LocalVariable { location, .. } => {
278
278
-
builder.variable(&self.generator.local_var_name(location))
278
278
+
builder.variable(&self.generator.local_var_name(location));
279
279
}
280
280
ValueConstructorVariant::ModuleFn { .. }
281
281
| ValueConstructorVariant::Record { .. } => panic!("invalid segment"),
···
1485
1485
}
1486
1486
match program.as_str() {
1487
1487
"erl" | "erlc" | "escript" => {
1488
1488
-
text.push_str(&brew_install("Erlang", "erlang"))
1488
1488
+
text.push_str(&brew_install("Erlang", "erlang"));
1489
1489
}
1490
1490
"rebar3" => text.push_str(&brew_install("Rebar3", "rebar3")),
1491
1491
"deno" => text.push_str(&brew_install("Deno", "deno")),
···
3460
3460
text.push_str(hint.as_str());
3461
3461
}
3462
3462
UnknownTypeHint::AlternativeTypes(_) => {}
3463
3463
-
};
3463
3463
+
}
3464
3464
3465
3465
Diagnostic {
3466
3466
title: "Unknown type".into(),
···
4647
4647
text.push_str(
4648
4648
"The only argument that was supplied is \
4649
4649
the `use` callback function.\n",
4650
4650
-
)
4650
4650
+
);
4651
4651
} else {
4652
4652
let _ = writeln!(
4653
4653
text,
···
4659
4659
text.push_str(
4660
4660
"All the arguments have already been supplied, \
4661
4661
so it cannot take the `use` callback function as a final argument.\n",
4662
4662
-
)
4663
4663
-
};
4662
4662
+
);
4663
4663
+
}
4664
4664
4665
4665
text.push_str("\nSee: https://tour.gleam.run/advanced-features/use/");
4666
4666
···
5250
5250
let mut new_lines = break_line(line, width);
5251
5251
lines.append(&mut new_lines);
5252
5252
}
5253
5253
-
};
5253
5253
+
}
5254
5254
}
5255
5255
5256
5256
lines
···
461
461
bit_array,
462
462
read_action: value,
463
463
},
464
464
-
))
464
464
+
));
465
465
}
466
466
467
467
fn assign_segment_constant_value(&mut self, name: EcoString, value: &BitArrayMatchedValue) {
···
478
478
}
479
479
};
480
480
481
481
-
self.bindings.push((name, value))
481
481
+
self.bindings.push((name, value));
482
482
}
483
483
}
484
484
···
1269
1269
let offset_other = other.read_action.from.constant_bits()?.to_usize()?;
1270
1270
if offset_one > offset_other {
1271
1271
return None;
1272
1272
-
};
1272
1272
+
}
1273
1273
1274
1274
// The second requirement is that: `o1 + s1 > o2`
1275
1275
let size_one = self.read_action.size.constant_bits()?.to_usize()?;
1276
1276
let size_other = other.read_action.size.constant_bits()?.to_usize()?;
1277
1277
if offset_one + size_one <= offset_other {
1278
1278
return None;
1279
1279
-
};
1279
1279
+
}
1280
1280
1281
1281
// At this point we know that both are interfering, so we compare the
1282
1282
// overlapping slice of bits they're matching against.
···
1998
1998
}
1999
1999
2000
2000
ReadSize::ConstantBits(..) | ReadSize::RemainingBits | ReadSize::RemainingBytes => (),
2001
2001
-
};
2001
2001
+
}
2002
2002
}
2003
2003
2004
2004
fn can_be_negative(&self) -> bool {
···
2564
2564
let mut remaining_choices = vec![];
2565
2565
for choice in choices.into_iter() {
2566
2566
if choice.0.is_ignored() {
2567
2567
-
ignored_checks.push(choice.0)
2567
2567
+
ignored_checks.push(choice.0);
2568
2568
} else {
2569
2569
-
remaining_choices.push(choice)
2569
2569
+
remaining_choices.push(choice);
2570
2570
}
2571
2571
}
2572
2572
···
3011
3011
if let Pattern::BitArray { tests } = pattern {
3012
3012
self.add_checked_bit_array_branch(pattern_check, tests, branch, compiler);
3013
3013
return;
3014
3014
-
};
3014
3014
+
}
3015
3015
3016
3016
let kind = pattern
3017
3017
.to_runtime_check_kind()
···
3367
3367
// it the same as an external type.
3368
3368
Opaque::Opaque if current_module != type_module => return Vec::new(),
3369
3369
Opaque::Opaque | Opaque::NotOpaque => {}
3370
3370
-
};
3370
3370
+
}
3371
3371
3372
3372
let specialiser = Self::new(constructors.type_parameters_ids.as_slice(), type_arguments);
3373
3373
constructors
···
3523
3523
.subject_variables
3524
3524
.get(i)
3525
3525
.expect("wrong number of subjects");
3526
3526
-
checks.push(var.is(pattern))
3526
3526
+
checks.push(var.is(pattern));
3527
3527
}
3528
3528
3529
3529
let guard = branch.guard.as_ref().map(|guard| {
···
3763
3763
};
3764
3764
tests.push_back(BitArrayTest::Size(SizeTest { operator, size }));
3765
3765
}
3766
3766
-
};
3766
3766
+
}
3767
3767
3768
3768
let type_ = match &segment.type_ {
3769
3769
type_ if type_.is_int() => ReadType::Int,
···
4098
4098
// No number is representable in 0 bits.
4099
4099
if bits == 0 {
4100
4100
return false;
4101
4101
-
};
4101
4101
+
}
4102
4102
4103
4103
let required_bits = match (value.sign(), signed) {
4104
4104
// Zero always needs one bit.
···
132
132
self.add_missing_patterns(fallback);
133
133
}
134
134
FallbackCheck::RuntimeCheck { check } => {
135
135
-
self.add_missing_patterns_after_check(var, check, fallback)
135
135
+
self.add_missing_patterns_after_check(var, check, fallback);
136
136
}
137
137
FallbackCheck::CatchAll { ignored_checks } => {
138
138
for check in ignored_checks {
139
139
self.add_missing_patterns_after_check(var, check, fallback);
140
140
}
141
141
}
142
142
-
};
142
142
+
}
143
143
}
144
144
}
145
145
}
···
192
192
terms,
193
193
mapping,
194
194
buffer,
195
195
-
)
195
195
+
);
196
196
} else {
197
197
buffer.push('_');
198
198
}
···
207
207
| Term::Infinite { .. }
208
208
| Term::List { .. } => {
209
209
buffer.push_str(", ");
210
210
-
self.print_list(term, terms, mapping, buffer)
210
210
+
self.print_list(term, terms, mapping, buffer);
211
211
}
212
212
}
213
213
} else {
···
222
222
223
223
if self.tracker.ok_used {
224
224
self.register_prelude_usage(arena, &mut imports, "Ok", None);
225
225
-
};
225
225
+
}
226
226
227
227
if self.tracker.error_used {
228
228
self.register_prelude_usage(arena, &mut imports, "Error", None);
229
229
-
};
229
229
+
}
230
230
231
231
if self.tracker.list_used {
232
232
self.register_prelude_usage(arena, &mut imports, "toList", None);
233
233
-
};
233
233
+
}
234
234
235
235
if self.tracker.list_empty_class_used || self.tracker.echo_used {
236
236
self.register_prelude_usage(arena, &mut imports, "Empty", Some("$Empty"));
237
237
-
};
237
237
+
}
238
238
239
239
if self.tracker.list_empty_const_used {
240
240
self.register_prelude_usage(
···
243
243
"List$Empty$const",
244
244
Some("$List$Empty$const"),
245
245
);
246
246
-
};
246
246
+
}
247
247
248
248
if self.tracker.list_non_empty_class_used || self.tracker.echo_used {
249
249
self.register_prelude_usage(arena, &mut imports, "NonEmpty", Some("$NonEmpty"));
250
250
-
};
250
250
+
}
251
251
252
252
if self.tracker.prepend_used {
253
253
self.register_prelude_usage(arena, &mut imports, "prepend", Some("listPrepend"));
254
254
-
};
254
254
+
}
255
255
256
256
if self.tracker.custom_type_used || self.tracker.echo_used {
257
257
self.register_prelude_usage(arena, &mut imports, "CustomType", Some("$CustomType"));
258
258
-
};
258
258
+
}
259
259
260
260
if self.tracker.make_error_used {
261
261
self.register_prelude_usage(arena, &mut imports, "makeError", None);
262
262
-
};
262
262
+
}
263
263
264
264
if self.tracker.int_remainder_used {
265
265
self.register_prelude_usage(arena, &mut imports, "remainderInt", None);
266
266
-
};
266
266
+
}
267
267
268
268
if self.tracker.float_division_used {
269
269
self.register_prelude_usage(arena, &mut imports, "divideFloat", None);
270
270
-
};
270
270
+
}
271
271
272
272
if self.tracker.int_division_used {
273
273
self.register_prelude_usage(arena, &mut imports, "divideInt", None);
274
274
-
};
274
274
+
}
275
275
276
276
if self.tracker.object_equality_used {
277
277
self.register_prelude_usage(arena, &mut imports, "isEqual", None);
278
278
-
};
278
278
+
}
279
279
280
280
if self.tracker.bit_array_literal_used {
281
281
self.register_prelude_usage(arena, &mut imports, "toBitArray", None);
···
780
780
index,
781
781
CLOSE_SQUARE_SEMICOLON_DOCUMENT
782
782
]
783
783
-
.group(arena)
783
783
+
.group(arena);
784
784
}
785
785
786
786
functions.push(docvec![
···
873
873
874
874
if constructor.arguments.is_empty() {
875
875
return docvec![arena, doc, head, CLOSE_CURLY_DOCUMENT];
876
876
-
};
876
876
+
}
877
877
878
878
let parameters = arena.join(
879
879
constructor
···
938
938
939
939
for custom_type in &self.module.definitions.custom_types {
940
940
if let Some(mut new_definitions) = self.custom_type_definition(arena, custom_type) {
941
941
-
definitions.append(&mut new_definitions)
941
941
+
definitions.append(&mut new_definitions);
942
942
}
943
943
}
944
944
945
945
for constant in &self.module.definitions.constants {
946
946
if let Some(definition) = self.module_constant(arena, constant) {
947
947
-
definitions.push(definition)
947
947
+
definitions.push(definition);
948
948
}
949
949
}
950
950
951
951
for function in &self.module.definitions.functions {
952
952
if let Some(definition) = self.module_function(arena, function) {
953
953
-
definitions.push(definition)
953
953
+
definitions.push(definition);
954
954
}
955
955
}
956
956
···
989
989
name,
990
990
module,
991
991
external_function,
992
992
-
)
992
992
+
);
993
993
}
994
994
}
995
995
···
1073
1073
},
1074
1074
};
1075
1075
if publicity.is_importable() {
1076
1076
-
imports.register_export(maybe_escape_identifier_string(name))
1076
1076
+
imports.register_export(maybe_escape_identifier_string(name));
1077
1077
}
1078
1078
imports.register_module(EcoString::from(module), [], [member]);
1079
1079
}
···
1249
1249
1250
1250
fn register_module_definitions_in_scope(&mut self) {
1251
1251
for constant in &self.module.definitions.constants {
1252
1252
-
self.register_in_scope(&constant.name)
1252
1252
+
self.register_in_scope(&constant.name);
1253
1253
}
1254
1254
1255
1255
for function in &self.module.definitions.functions {
···
1260
1260
1261
1261
for import in &self.module.definitions.imports {
1262
1262
for unqualified_value in &import.unqualified_values {
1263
1263
-
self.register_in_scope(unqualified_value.used_name())
1263
1263
+
self.register_in_scope(unqualified_value.used_name());
1264
1264
}
1265
1265
}
1266
1266
}
···
500
500
let name = self.variables.next_local_var(&ASSIGNMENT_VAR.into());
501
501
let value = self.variables.get_value(var);
502
502
self.variables.bind(name.clone(), var);
503
503
-
assignments.push(let_doc(arena, name, value.to_doc(arena)))
504
504
-
};
503
503
+
assignments.push(let_doc(arena, name, value.to_doc(arena)));
504
504
+
}
505
505
506
506
// Variable storing the character code for the first character of a string.
507
507
// This is only declared if multiple patterns match on just the first
···
734
734
735
735
match &self.kind {
736
736
DecisionKind::Case { .. } => {
737
737
-
self.variables.expression_generator.current_scope = old_scope
737
737
+
self.variables.expression_generator.current_scope = old_scope;
738
738
}
739
739
DecisionKind::LetAssert { .. } => {}
740
740
}
···
1652
1652
if *times != 1 {
1653
1653
variable = variable
1654
1654
.append(arena, SPACE_TIMES_SPACE_DOCUMENT)
1655
1655
-
.append(arena, *times)
1655
1655
+
.append(arena, *times);
1656
1656
}
1657
1657
-
pieces.push(variable.to_doc(arena))
1657
1657
+
pieces.push(variable.to_doc(arena));
1658
1658
}
1659
1659
1660
1660
for calculation in offset.calculations.iter() {
···
1670
1670
);
1671
1671
1672
1672
if parenthesise {
1673
1673
-
pieces.push(calculation.surround(arena, OPEN_PAREN_DOCUMENT, CLOSE_PAREN_DOCUMENT))
1673
1673
+
pieces.push(calculation.surround(arena, OPEN_PAREN_DOCUMENT, CLOSE_PAREN_DOCUMENT));
1674
1674
} else {
1675
1675
-
pieces.push(calculation)
1675
1675
+
pieces.push(calculation);
1676
1676
}
1677
1677
}
1678
1678
···
2081
2081
2082
2082
RuntimeCheck::BitArray { test } => {
2083
2083
for (segment_name, read_action) in test.referenced_segment_patterns() {
2084
2084
-
self.set_segment_value(arena, variable, segment_name.clone(), read_action)
2084
2084
+
self.set_segment_value(arena, variable, segment_name.clone(), read_action);
2085
2085
}
2086
2086
}
2087
2087
···
2138
2138
.get_segment_value(arena, segment)
2139
2139
.expect("segment referenced in a check before being created");
2140
2140
self.bind_segment(variable_name.clone(), segment.clone());
2141
2141
-
check_assignments.push(let_doc(arena, variable_name, segment_value))
2141
2141
+
check_assignments.push(let_doc(arena, variable_name, segment_value));
2142
2142
}
2143
2143
check_assignments
2144
2144
}
···
38
38
.entry(path.clone())
39
39
.or_insert_with(|| Import::new(path.clone()));
40
40
import.aliases.extend(aliases);
41
41
-
import.unqualified.extend(unqualified_imports)
41
41
+
import.unqualified.extend(unqualified_imports);
42
42
}
43
43
44
44
pub fn into_doc(
···
106
106
},
107
107
Type::Named { arguments, .. } => {
108
108
for argument in arguments {
109
109
-
generic_ids(argument, ids)
109
109
+
generic_ids(argument, ids);
110
110
}
111
111
}
112
112
Type::Fn { arguments, return_ } => {
113
113
for argument in arguments {
114
114
-
generic_ids(argument, ids)
114
114
+
generic_ids(argument, ids);
115
115
}
116
116
generic_ids(return_, ids);
117
117
}
118
118
Type::Tuple { elements } => {
119
119
for element in elements {
120
120
-
generic_ids(element, ids)
120
120
+
generic_ids(element, ids);
121
121
}
122
122
}
123
123
}
···
595
595
596
596
if constructor.arguments.is_empty() {
597
597
return head.append(arena, CLOSE_CURLY_DOCUMENT);
598
598
-
};
598
598
+
}
599
599
600
600
let class_body = docvec![
601
601
arena,
···
676
676
name,
677
677
COLON_SPACE_DOCUMENT,
678
678
self.do_print_force_generic_param(arena, ¶meter.type_)
679
679
-
])
679
679
+
]);
680
680
}
681
681
682
682
let function_name = eco_format!(
···
743
743
}
744
744
}
745
745
document = document.append(arena, GT_INT_DOCUMENT);
746
746
-
};
746
746
+
}
747
747
document = document.append(arena, SEMICOLON_DOCUMENT);
748
748
document.group(arena)
749
749
}
···
1227
1227
/// Allows an outside module to mark the Gleam prelude as "used"
1228
1228
///
1229
1229
pub fn set_prelude_used(&mut self) {
1230
1230
-
self.tracker.prelude_used = true
1230
1230
+
self.tracker.prelude_used = true;
1231
1231
}
1232
1232
1233
1233
/// Returns if the Gleam prelude has been used at all during the process
···
441
441
match self.parse_expression_unit(expression_unit_context)? {
442
442
Some(unit) => {
443
443
self.post_process_expression_unit(&unit, is_let_binding)?;
444
444
-
estack.push(unit)
444
444
+
estack.push(unit);
445
445
}
446
446
_ if estack.is_empty() => return Ok(None),
447
447
_ => {
···
649
649
Ok(elements) => {
650
650
elements_after_tail = Some(elements);
651
651
}
652
652
-
};
653
653
-
};
652
652
+
}
653
653
+
}
654
654
655
655
if tail.is_some() {
656
656
if !elements_end_with_comma {
···
1549
1549
Ok(elements) => {
1550
1550
elements_after_tail = Some(elements);
1551
1551
}
1552
1552
-
};
1553
1553
-
};
1552
1552
+
}
1553
1553
+
}
1554
1554
Some(tail)
1555
1555
}
1556
1556
_ => None,
···
1604
1604
start,
1605
1605
end: closing_square_bracket_end,
1606
1606
},
1607
1607
-
})
1607
1607
+
});
1608
1608
}
1609
1609
1610
1610
Pattern::List {
···
2057
2057
self.warnings
2058
2058
.push(DeprecatedSyntaxWarning::DeprecatedRecordSpreadPattern {
2059
2059
location: spread_location,
2060
2060
-
})
2060
2060
+
});
2061
2061
}
2062
2062
}
2063
2063
let (_, end) = self.expect_one(&Token::RightParen)?;
···
2222
2222
end: colon_end,
2223
2223
},
2224
2224
});
2225
2225
-
};
2225
2225
+
}
2226
2226
2227
2227
let return_annotation = self.parse_type_annotation(&Token::RArrow)?;
2228
2228
···
3138
3138
},
3139
3139
location: SrcSpan::new(dot_start, dot_end),
3140
3140
});
3141
3141
-
};
3141
3141
+
}
3142
3142
3143
3143
let parsed = self.parse_unqualified_imports()?;
3144
3144
unqualified_types = parsed.types;
···
3201
3201
import.as_name = Some(as_name);
3202
3202
import.location.end = end;
3203
3203
}
3204
3204
-
imports.values.push(import)
3204
3204
+
imports.values.push(import);
3205
3205
}
3206
3206
3207
3207
Some((start, Token::UpName { name }, end)) => {
···
3218
3218
import.as_name = Some(as_name);
3219
3219
import.location.end = end;
3220
3220
}
3221
3221
-
imports.values.push(import)
3221
3221
+
imports.values.push(import);
3222
3222
}
3223
3223
3224
3224
Some((start, Token::Type, _)) => {
···
3236
3236
import.as_name = Some(as_name);
3237
3237
import.location.end = end;
3238
3238
}
3239
3239
-
imports.types.push(import)
3239
3239
+
imports.types.push(import);
3240
3240
}
3241
3241
3242
3242
t0 => {
···
3413
3413
Ok(elements) => {
3414
3414
elements_after_tail = Some(elements);
3415
3415
}
3416
3416
-
};
3417
3417
-
};
3416
3416
+
}
3417
3417
+
}
3418
3418
3419
3419
if tail.is_some() {
3420
3420
// Give a better error when there are two lists being
···
4443
4443
// If the sequence ends with a trailing comma we want to keep track of
4444
4444
// its position.
4445
4445
if let (Some(Token::Comma), Some((_, end))) = (sep, final_separator) {
4446
4446
-
self.extra.trailing_commas.push(end)
4447
4447
-
};
4446
4446
+
self.extra.trailing_commas.push(end);
4447
4447
+
}
4448
4448
4449
4449
Ok((results, final_separator.is_some()))
4450
4450
}
···
4810
4810
fn precedence(t: &Token) -> Option<u8> {
4811
4811
if t == &Token::Pipe {
4812
4812
return Some(6);
4813
4813
-
};
4813
4813
+
}
4814
4814
tok_to_binop(t).map(|op| op.precedence())
4815
4815
}
4816
4816
···
5327
5327
5328
5328
impl Hash for LiteralFloatValue {
5329
5329
fn hash<H: Hasher>(&self, state: &mut H) {
5330
5330
-
self.0.to_bits().hash(state)
5330
5330
+
self.0.to_bits().hash(state);
5331
5331
}
5332
5332
}
5333
5333
···
103
103
// Transform windows EOL into \n
104
104
let _ = self.shift();
105
105
// using the position from the \r
106
106
-
self.chr0 = Some((i, '\n'))
106
106
+
self.chr0 = Some((i, '\n'));
107
107
} else {
108
108
// Transform MAC EOL into \n
109
109
-
self.chr0 = Some((i, '\n'))
109
109
+
self.chr0 = Some((i, '\n'));
110
110
}
111
111
}
112
112
···
156
156
let mut check_for_minus = false;
157
157
if self.is_upname_start(c) {
158
158
let name = self.lex_upname()?;
159
159
-
self.emit(name)
159
159
+
self.emit(name);
160
160
} else if self.is_name_start(c) {
161
161
check_for_minus = true;
162
162
let name = self.lex_name()?;
···
207
207
end: tok_end + 1,
208
208
},
209
209
});
210
210
-
};
210
210
+
}
211
211
self.emit((tok_start, Token::EqualEqual, tok_end));
212
212
}
213
213
_ => {
···
844
844
let start_pos = self.get_pos();
845
845
846
846
while self.is_name_continuation() {
847
847
-
name.push(self.next_char().expect("lex_name continue"))
847
847
+
name.push(self.next_char().expect("lex_name continue"));
848
848
}
849
849
850
850
let end_pos = self.get_pos();
···
188
188
pub fn unnest(within: &Utf8Path) -> Utf8PathBuf {
189
189
let mut path = Utf8PathBuf::new();
190
190
for _ in within {
191
191
-
path = path.join("..")
191
191
+
path = path.join("..");
192
192
}
193
193
path
194
194
}
···
577
577
EntityKind::ImportedConstructor { module }
578
578
| EntityKind::ImportedType { module }
579
579
| EntityKind::ImportedValue { module } => {
580
580
-
self.register_module_reference(module.clone())
580
580
+
self.register_module_reference(module.clone());
581
581
}
582
582
}
583
583
}
···
639
639
}
640
640
ReferenceKind::Import(_) | ReferenceKind::Definition => {}
641
641
ReferenceKind::Alias | ReferenceKind::Unqualified => {
642
642
-
self.register_type_reference_in_call_graph(referenced_name.clone())
642
642
+
self.register_type_reference_in_call_graph(referenced_name.clone());
643
643
}
644
644
}
645
645
···
43
43
/// Register an error.
44
44
///
45
45
pub fn error(&mut self, error: Error) {
46
46
-
self.errors.push(error)
46
46
+
self.errors.push(error);
47
47
}
48
48
49
49
/// Register a warning.
50
50
///
51
51
pub fn warning(&mut self, warning: Warning) {
52
52
-
self.warnings.push(warning)
52
52
+
self.warnings.push(warning);
53
53
}
54
54
55
55
/// Take all the errors, leaving an empty vector in its place.
···
658
658
self.problems.warning(Warning::UnreachableCodeAfterPanic {
659
659
location,
660
660
panic_position,
661
661
-
})
661
661
+
});
662
662
}
663
663
}
664
664
···
708
708
} else if discarded.is_pure_value_constructor() {
709
709
self.problems.warning(Warning::UnusedValue {
710
710
location: discarded.location(),
711
711
-
})
711
711
+
});
712
712
}
713
713
}
714
714
···
1252
1252
self.problems.error(convert_unify_error(
1253
1253
error.list_element_mismatch(),
1254
1254
element.location(),
1255
1255
-
))
1256
1256
-
};
1255
1255
+
));
1256
1256
+
}
1257
1257
inferred_elements.push(element);
1258
1258
}
1259
1259
···
1267
1267
self.problems.error(convert_unify_error(
1268
1268
error.list_tail_mismatch(),
1269
1269
tail.location(),
1270
1270
-
))
1270
1270
+
));
1271
1271
}
1272
1272
Some(Box::new(tail))
1273
1273
}
···
1443
1443
&constructor.variant,
1444
1444
*location,
1445
1445
ReferenceKind::Unqualified,
1446
1446
-
)
1446
1446
+
);
1447
1447
}
1448
1448
}
1449
1449
record_access
···
1631
1631
);
1632
1632
segment.options.push(BitArrayOption::Float {
1633
1633
location: SrcSpan::default(),
1634
1634
-
})
1634
1634
+
});
1635
1635
}
1636
1636
1637
1637
UntypedExpr::Int { .. }
···
1668
1668
// check if it's `size` option uses any feature that has to
1669
1669
// be tracked!
1670
1670
self.check_segment_size_expression(&segment.options);
1671
1671
-
};
1671
1671
+
}
1672
1672
1673
1673
segment
1674
1674
})
···
1712
1712
);
1713
1713
segment.options.push(BitArrayOption::Float {
1714
1714
location: SrcSpan::default(),
1715
1715
-
})
1715
1715
+
});
1716
1716
}
1717
1717
1718
1718
Constant::Int { .. }
···
1863
1863
let expression = self.infer(expression);
1864
1864
if let Err(error) = unify(type_, expression.type_()) {
1865
1865
self.problems
1866
1866
-
.error(convert_unify_error(error, expression.location()))
1866
1866
+
.error(convert_unify_error(error, expression.location()));
1867
1867
}
1868
1868
expression
1869
1869
}
···
1942
1942
self.problems.error(Error::FloatOperatorOnInts {
1943
1943
operator,
1944
1944
location: SrcSpan::new(operator_start, operator_start + operator.size()),
1945
1945
-
})
1945
1945
+
});
1946
1946
} else if operator.is_int_operator() && left.type_().is_float() && right.type_().is_float()
1947
1947
{
1948
1948
self.problems.error(Error::IntOperatorOnFloats {
1949
1949
operator,
1950
1950
location: SrcSpan::new(operator_start, operator_start + operator.size()),
1951
1951
-
})
1951
1951
+
});
1952
1952
} else if operator == BinOp::AddInt && left.type_().is_string() && right.type_().is_string()
1953
1953
{
1954
1954
self.problems.error(Error::StringConcatenationWithAddInt {
1955
1955
location: SrcSpan::new(operator_start, operator_start + operator.size()),
1956
1956
-
})
1956
1956
+
});
1957
1957
} else {
1958
1958
// In all other cases we just report an error for each of the operands.
1959
1959
if let Err(error) = unify_left {
···
2249
2249
| Reachability::Unreachable(UnreachablePatternReason::DuplicatePattern) => {}
2250
2250
}
2251
2251
}
2252
2252
-
};
2252
2252
+
}
2253
2253
2254
2254
Assignment {
2255
2255
location,
···
2378
2378
self.previous_panics = false;
2379
2379
let (typed_clause, error_typing_patterns) = self.infer_clause(clause, &typed_subjects);
2380
2380
if error_typing_patterns {
2381
2381
-
patterns_typechecked_successfully = false
2381
2381
+
patterns_typechecked_successfully = false;
2382
2382
}
2383
2383
all_clauses_panic = all_clauses_panic && self.previous_panics;
2384
2384
···
2639
2639
let expression = self.infer_clause_guard(*expression);
2640
2640
if let Err(error) = unify(bool(), expression.type_()) {
2641
2641
self.problems
2642
2642
-
.error(convert_unify_error(error, expression.location()))
2643
2643
-
};
2642
2642
+
.error(convert_unify_error(error, expression.location()));
2643
2643
+
}
2644
2644
ClauseGuard::Not {
2645
2645
location,
2646
2646
expression: Box::new(expression),
···
2949
2949
location: select_location,
2950
2950
message: message.clone(),
2951
2951
layer: Layer::Value,
2952
2952
-
})
2952
2952
+
});
2953
2953
}
2954
2954
2955
2955
self.environment
···
3272
3272
// We still want to accumulate errors for all field to come!
3273
3273
if let Err(error) = unify(variant.arg_type(index), value.type_()) {
3274
3274
self.problems.error(convert_unify_error(error, *location));
3275
3275
-
};
3275
3275
+
}
3276
3276
3277
3277
if let Some(type_name) = return_type.named_type_name() {
3278
3278
self.environment.references.register_label_reference(
···
3291
3291
value,
3292
3292
implicit: None,
3293
3293
},
3294
3294
-
))
3294
3294
+
));
3295
3295
} else if variant.has_field(label) {
3296
3296
// The variant has this field but it was already removed in a
3297
3297
// previous iteration. This means we've found a duplicate field!
3298
3298
self.problems.error(Error::DuplicateArgument {
3299
3299
location: *location,
3300
3300
label: label.clone(),
3301
3301
-
})
3301
3301
+
});
3302
3302
} else {
3303
3303
// Otherwise, it's just an unknown field!
3304
3304
self.problems.error(self.unknown_field_error(
···
3307
3307
*location,
3308
3308
label.clone(),
3309
3309
FieldAccessUsage::RecordUpdate,
3310
3310
-
))
3311
3311
-
};
3310
3310
+
));
3311
3311
+
}
3312
3312
}
3313
3313
3314
3314
// Generate the remaining copied arguments, making sure they unify with
···
3363
3363
value: record_access,
3364
3364
implicit: Some(ImplicitCallArgOrigin::RecordUpdate),
3365
3365
},
3366
3366
-
))
3366
3366
+
));
3367
3367
} else {
3368
3368
let (accessor_type, positional_fields) =
3369
3369
match collapse_links(record.type_()).as_ref() {
···
3457
3457
value: record_access,
3458
3458
implicit: Some(ImplicitCallArgOrigin::RecordUpdate),
3459
3459
},
3460
3460
-
))
3460
3460
+
));
3461
3461
}
3462
3462
}
3463
3463
···
3733
3733
location: *location,
3734
3734
message: message.clone(),
3735
3735
layer: Layer::Value,
3736
3736
-
})
3736
3736
+
});
3737
3737
}
3738
3738
3739
3739
self.narrow_implementations(*location, &variant)?;
···
3830
3830
referenced_name,
3831
3831
location,
3832
3832
ReferenceKind::Alias,
3833
3833
-
)
3833
3833
+
);
3834
3834
}
3835
3835
ValueConstructorVariant::ModuleFn { name, module, .. }
3836
3836
| ValueConstructorVariant::Record { name, module, .. }
···
3841
3841
referenced_name,
3842
3842
location,
3843
3843
kind,
3844
3844
-
)
3844
3844
+
);
3845
3845
}
3846
3846
ValueConstructorVariant::LocalVariable { .. } => {
3847
3847
-
self.environment.increment_usage(referenced_name)
3847
3847
+
self.environment.increment_usage(referenced_name);
3848
3848
}
3849
3849
}
3850
3850
}
···
4295
4295
error
4296
4296
.operator_situation(BinOp::Concatenate)
4297
4297
.into_error(left.location()),
4298
4298
-
)
4299
4299
-
};
4298
4298
+
);
4299
4299
+
}
4300
4300
4301
4301
let right = self.infer_const(&None, *right);
4302
4302
if let Err(error) = unify(string(), right.type_()) {
···
4304
4304
error
4305
4305
.operator_situation(BinOp::Concatenate)
4306
4306
.into_error(right.location()),
4307
4307
-
)
4308
4308
-
};
4307
4307
+
);
4308
4308
+
}
4309
4309
4310
4310
Constant::StringConcatenation {
4311
4311
location,
···
4322
4322
let message = self.infer_const(&None, *message);
4323
4323
if let Err(error) = unify(string(), message.type_()) {
4324
4324
self.problems
4325
4325
-
.error(convert_unify_error(error, message.location()))
4325
4325
+
.error(convert_unify_error(error, message.location()));
4326
4326
}
4327
4327
Box::new(message)
4328
4328
});
···
4476
4476
let value = self.infer_const(&None, value);
4477
4477
if let Err(error) = unify(type_.clone(), value.type_()) {
4478
4478
self.problems
4479
4479
-
.error(convert_unify_error(error, value.location()))
4479
4479
+
.error(convert_unify_error(error, value.location()));
4480
4480
}
4481
4481
CallArg {
4482
4482
label,
···
4546
4546
},
4547
4547
implicit,
4548
4548
location,
4549
4549
-
})
4549
4549
+
});
4550
4550
}
4551
4551
4552
4552
Constant::Record {
···
4652
4652
let tail = self.infer_const(&None, *tail);
4653
4653
if let Err(error) = unify(type_.clone(), tail.type_()) {
4654
4654
self.problems
4655
4655
-
.error(convert_unify_error(error, tail.location()))
4655
4655
+
.error(convert_unify_error(error, tail.location()));
4656
4656
}
4657
4657
Some(Box::new(tail))
4658
4658
} else {
···
4954
4954
});
4955
4955
}
4956
4956
arguments.push(last);
4957
4957
-
};
4957
4957
+
}
4958
4958
4959
4959
// Ensure that the given args have the correct types
4960
4960
let arguments_count = arguments_types.len();
···
4997
4997
self.warn_for_unreachable_code(
4998
4998
value.location(),
4999
4999
PanicPosition::PreviousFunctionArgument,
5000
5000
-
)
5000
5000
+
);
5001
5001
}
5002
5002
5003
5003
let value = self.infer_call_argument(
···
5078
5078
},
5079
5079
implicit,
5080
5080
location,
5081
5081
-
})
5081
5081
+
});
5082
5082
}
5083
5083
5084
5084
// We don't want to emit a warning for unreachable function call if the
···
5294
5294
}
5295
5295
}
5296
5296
ArgNames::Discard { .. } | ArgNames::LabelledDiscard { .. } => (),
5297
5297
-
};
5297
5297
+
}
5298
5298
}
5299
5299
5300
5300
if let Ok(body) = Vec1::try_from_vec(body) {
···
5324
5324
},
5325
5325
type_: body_typer.new_unbound_var(),
5326
5326
extra_information: None,
5327
5327
-
}))
5328
5328
-
};
5327
5327
+
}));
5328
5328
+
}
5329
5329
5330
5330
Ok((arguments, body.to_vec()))
5331
5331
} else {
···
5407
5407
let location = SrcSpan::new(first.location().start, last.location().end);
5408
5408
5409
5409
self.problems
5410
5410
-
.warning(Warning::UnreachableCasePattern { location, reason })
5410
5410
+
.warning(Warning::UnreachableCasePattern { location, reason });
5411
5411
}
5412
5412
}
5413
5413
}
···
5435
5435
feature_kind,
5436
5436
minimum_required_version: minimum_required_version.clone(),
5437
5437
wrongfully_allowed_version: lowest_allowed_version,
5438
5438
-
})
5438
5438
+
});
5439
5439
}
5440
5440
}
5441
5441
···
5476
5476
5477
5477
// Blocks and binops were added in Gleam 1.12.0!
5478
5478
TypedExpr::Block { location, .. } | TypedExpr::BinOp { location, .. } => {
5479
5479
-
self.track_feature_usage(FeatureKind::ExpressionInSegmentSize, *location)
5479
5479
+
self.track_feature_usage(FeatureKind::ExpressionInSegmentSize, *location);
5480
5480
}
5481
5481
5482
5482
// None of these are currently supported... for now!
···
6095
6095
};
6096
6096
assignments
6097
6097
.body_assignments
6098
6098
-
.push(Statement::Assignment(Box::new(assignment)))
6098
6098
+
.push(Statement::Assignment(Box::new(assignment)));
6099
6099
}
6100
6100
}
6101
6101
}
···
6248
6248
},
6249
6249
(None, Some(_)) | (Some(_), None) => return StaticComparison::CantTell,
6250
6250
(None, None) => (),
6251
6251
-
};
6251
6251
+
}
6252
6252
6253
6253
// If we can tell the two lists have a different number of items
6254
6254
// then we know it's never going to match.
···
79
79
}
80
80
81
81
pub fn disallow_new_type_variables(&mut self) {
82
82
-
self.permit_new_type_variables = false
82
82
+
self.permit_new_type_variables = false;
83
83
}
84
84
85
85
pub fn permit_holes(&mut self, flag: bool) {
86
86
-
self.permit_holes = flag
86
86
+
self.permit_holes = flag;
87
87
}
88
88
89
89
/// A rigid type is a generic type that was specified as being generic in
···
211
211
location: *location,
212
212
message,
213
213
layer: Layer::Type,
214
214
-
})
214
214
+
});
215
215
}
216
216
}
217
217
···
179
179
self.problems.error(convert_unify_error(error, location));
180
180
self.error_encountered = true;
181
181
}
182
182
-
};
182
182
+
}
183
183
unify_constructor_variants(Arc::make_mut(&mut initial.type_), &type_);
184
184
}
185
185
···
435
435
436
436
if let Some(s) = last_segment {
437
437
let typed_last_segment = self.infer_pattern_segment(s, true);
438
438
-
typed_segments.push(typed_last_segment)
438
438
+
typed_segments.push(typed_last_segment);
439
439
}
440
440
441
441
TypedPattern::BitArray {
···
466
466
self.track_feature_usage(FeatureKind::UnannotatedFloatSegment, *location);
467
467
segment.options.push(BitArrayOption::Float {
468
468
location: SrcSpan::default(),
469
469
-
})
469
469
+
});
470
470
}
471
471
472
472
Pattern::Int { .. }
···
640
640
| Pattern::BitArray { .. }
641
641
| Pattern::StringPrefix { .. }
642
642
| Pattern::Invalid { .. } => {}
643
643
-
};
643
643
+
}
644
644
645
645
let typed_segment = BitArraySegment {
646
646
location: segment.location,
···
772
772
.insert(right.clone(), right_location);
773
773
self.check_name_case(right_location, right, Named::Discard);
774
774
}
775
775
-
};
775
775
+
}
776
776
777
777
Pattern::StringPrefix {
778
778
location,
···
1141
1141
implicit: Some(ImplicitCallArgOrigin::PatternFieldSpread),
1142
1142
});
1143
1143
}
1144
1144
-
};
1144
1144
+
}
1145
1145
}
1146
1146
}
1147
1147
···
1190
1190
location,
1191
1191
message,
1192
1192
layer: Layer::Value,
1193
1193
-
})
1193
1193
+
});
1194
1194
}
1195
1195
}
1196
1196
···
1328
1328
&& let Some(label) = &arg.label
1329
1329
&& let Some(field) = field_map.fields.get(label)
1330
1330
{
1331
1331
-
index = *field as usize
1331
1331
+
index = *field as usize;
1332
1332
}
1333
1333
}
1334
1334
···
1441
1441
location,
1442
1442
ReferenceKind::Unqualified,
1443
1443
),
1444
1444
-
};
1444
1444
+
}
1445
1445
1446
1446
self.environment.increment_usage(&name);
1447
1447
let type_ = self.environment.instantiate(
···
1515
1515
feature_kind,
1516
1516
minimum_required_version: minimum_required_version.clone(),
1517
1517
wrongfully_allowed_version: lowest_allowed_version,
1518
1518
-
})
1518
1518
+
});
1519
1519
}
1520
1520
}
1521
1521
···
1557
1557
BitArraySize::Int { .. } | BitArraySize::Variable { .. } => (),
1558
1558
BitArraySize::BinaryOperator { location, .. }
1559
1559
| BitArraySize::Block { location, .. } => {
1560
1560
-
self.track_feature_usage(FeatureKind::ExpressionInSegmentSize, *location)
1560
1560
+
self.track_feature_usage(FeatureKind::ExpressionInSegmentSize, *location);
1561
1561
}
1562
1562
}
1563
1563
}
···
270
270
if print_mode == PrintMode::ExpandAliases {
271
271
if let Some((module, _)) = self.imported_modules.get(module) {
272
272
return NameContextInformation::Qualified(module, name.as_str());
273
273
-
};
273
273
+
}
274
274
275
275
return NameContextInformation::Unimported(module, name);
276
276
}
···
294
294
// This type is from a module that has been imported
295
295
if let Some((module, _)) = self.imported_modules.get(module) {
296
296
return NameContextInformation::Qualified(module, name.as_str());
297
297
-
};
297
297
+
}
298
298
299
299
NameContextInformation::Unimported(module, name)
300
300
}
···
328
328
// This value is from a module that has been imported
329
329
if let Some((module, _)) = self.imported_modules.get(module) {
330
330
return NameContextInformation::Qualified(module, name.as_str());
331
331
-
};
331
331
+
}
332
332
333
333
NameContextInformation::Unimported(module, name)
334
334
}
···
517
517
Type::Var { type_, .. } => match *type_.borrow() {
518
518
TypeVar::Link { ref type_, .. } => self.print(type_, buffer, print_mode),
519
519
TypeVar::Unbound { id, .. } | TypeVar::Generic { id, .. } => {
520
520
-
buffer.push_str(&self.type_variable(id))
520
520
+
buffer.push_str(&self.type_variable(id));
521
521
}
522
522
},
523
523
···
593
593
if rest == 0 {
594
594
break;
595
595
}
596
596
-
rest -= 1
596
596
+
rest -= 1;
597
597
}
598
598
599
599
self.uid += 1;
···
235
235
elements.last().map(|element| element.location()),
236
236
),
237
237
Some(Pattern::Discard { location, .. }) => {
238
238
-
self.discard_tuple_items(*location, elements.len())
238
238
+
self.discard_tuple_items(*location, elements.len());
239
239
}
240
240
_ => panic!("safe: we've just checked all patterns must be discards/tuples"),
241
241
}
···
244
244
self.hovered = self.hovered || overlaps(self.params.range, range);
245
245
}
246
246
247
247
-
ast::visit::visit_typed_expr_case(self, location, type_, subjects, clauses, compiled_case)
247
247
+
ast::visit::visit_typed_expr_case(self, location, type_, subjects, clauses, compiled_case);
248
248
}
249
249
}
250
250
···
339
339
self.edits.replace(
340
340
discard_location,
341
341
itertools::intersperse(iter::repeat_n("_", tuple_items), ", ").collect(),
342
342
-
)
342
342
+
);
343
343
}
344
344
}
345
345
···
725
725
value: TypedExpr::Var { name, location, .. },
726
726
..
727
727
} if is_selected && !arg.uses_label_shorthand() && label == name => {
728
728
-
self.edits.delete(*location)
728
728
+
self.edits.delete(*location);
729
729
}
730
730
_ => (),
731
731
}
732
732
733
733
-
ast::visit::visit_typed_call_arg(self, arg)
733
733
+
ast::visit::visit_typed_call_arg(self, arg);
734
734
}
735
735
736
736
fn visit_typed_pattern_call_arg(&mut self, arg: &'ast CallArg<TypedPattern>) {
···
743
743
value: TypedPattern::Variable { name, location, .. },
744
744
..
745
745
} if is_selected && !arg.uses_label_shorthand() && label == name => {
746
746
-
self.edits.delete(*location)
746
746
+
self.edits.delete(*location);
747
747
}
748
748
_ => (),
749
749
}
750
750
751
751
-
ast::visit::visit_typed_pattern_call_arg(self, arg)
751
751
+
ast::visit::visit_typed_pattern_call_arg(self, arg);
752
752
}
753
753
}
754
754
···
996
996
.as_ref()
997
997
.map(|constructor| constructor.type_.clone()),
998
998
enclosing_function: None,
999
999
-
})
999
999
+
});
1000
1000
}
1001
1001
1002
1002
// We only want to take into account the innermost function call
···
1037
1037
kind: SelectedCallKind::Value,
1038
1038
fun_type: Some(fun.type_()),
1039
1039
enclosing_function: self.current_function,
1040
1040
-
})
1040
1040
+
});
1041
1041
}
1042
1042
1043
1043
// We only want to take into account the innermost function call
···
1074
1074
kind: SelectedCallKind::Pattern,
1075
1075
fun_type: None,
1076
1076
enclosing_function: self.current_function,
1077
1077
-
})
1077
1077
+
});
1078
1078
}
1079
1079
1080
1080
ast::visit::visit_typed_pattern_constructor(
···
1265
1265
import_location,
1266
1266
import,
1267
1267
&after_import_newlines,
1268
1268
-
))
1269
1269
-
};
1268
1268
+
));
1269
1269
+
}
1270
1270
1271
1271
let title = match &suggestion.import {
1272
1272
Some(import) => &format!("Import `{import}`"),
···
1765
1765
// which is lacking some annotations in the module
1766
1766
if !self.is_hovering_definition_requiring_annotations {
1767
1767
return vec![];
1768
1768
-
};
1768
1768
+
}
1769
1769
1770
1770
let mut action = Vec::with_capacity(1);
1771
1771
CodeActionBuilder::new("Annotate all top level definitions")
···
2024
2024
module_name,
2025
2025
module_alias,
2026
2026
constructor,
2027
2027
-
)
2027
2027
+
);
2028
2028
}
2029
2029
2030
2030
fn visit_typed_pattern_constructor(
···
2168
2168
self.edits.delete(SrcSpan {
2169
2169
start: location.start,
2170
2170
end: location.start + self.qualified_constructor.used_name.len() as u32 + 1, // plus .
2171
2171
-
})
2171
2171
+
});
2172
2172
}
2173
2173
2174
2174
fn edit_import(&mut self) {
···
2258
2258
module_name,
2259
2259
module_alias,
2260
2260
constructor,
2261
2261
-
)
2261
2261
+
);
2262
2262
}
2263
2263
2264
2264
fn visit_typed_pattern_constructor(
···
2431
2431
layer: ast::Layer::Value,
2432
2432
})
2433
2433
})
2434
2434
-
})
2434
2434
+
});
2435
2435
}
2436
2436
2437
2437
fn get_module_import_from_type_constructor(&mut self, constructor_name: &EcoString) {
···
2454
2454
});
2455
2455
}
2456
2456
None
2457
2457
-
})
2457
2457
+
});
2458
2458
}
2459
2459
}
2460
2460
···
2992
2992
} else {
2993
2993
callback_start
2994
2994
},
2995
2995
-
)
2995
2995
+
);
2996
2996
} else {
2997
2997
// On the other hand, if the function on the right hand side doesn't
2998
2998
// end with a closed parenthese then we have to manually add it.
···
3001
3001
// ^ No parentheses
3002
3002
//
3003
3003
self.edits
3004
3004
-
.insert(use_line_end, format!("(fn({assignments}) {{"))
3005
3005
-
};
3004
3004
+
.insert(use_line_end, format!("(fn({assignments}) {{"));
3005
3005
+
}
3006
3006
3007
3007
// Then we have to increase indentation for all the lines of the use
3008
3008
// body.
···
3016
3016
end: Position { line, character: 0 },
3017
3017
},
3018
3018
new_text: " ".to_string(),
3019
3019
-
})
3019
3019
+
});
3020
3020
}
3021
3021
3022
3022
let final_line_indentation = " ".repeat(use_body_range.start.character as usize);
···
3158
3158
SrcSpan::new(arg_before_callback.end, callback_body_span.start),
3159
3159
format!(")\n{indentation}"),
3160
3160
),
3161
3161
-
};
3161
3161
+
}
3162
3162
3163
3163
// Then we have to remove two spaces of indentation from each line of
3164
3164
// the callback function's body.
···
3167
3167
self.edits.delete_range(Range::new(
3168
3168
Position { line, character: 0 },
3169
3169
Position { line, character: 2 },
3170
3170
-
))
3170
3170
+
));
3171
3171
}
3172
3172
3173
3173
// Then we have to remove the anonymous fn closing `}` and the call's
···
3199
3199
self.selected_call = Some(call_data);
3200
3200
}
3201
3201
3202
3202
-
ast::visit::visit_typed_function(self, fun)
3202
3202
+
ast::visit::visit_typed_function(self, fun);
3203
3203
}
3204
3204
3205
3205
fn visit_typed_expr_fn(
···
3246
3246
if within(self.params.range, statement_range) {
3247
3247
// Only the last statement of a block can be turned into a use!
3248
3248
if let Some(selected_call) = turn_statement_into_use(last_statement) {
3249
3249
-
self.selected_call = Some(selected_call)
3249
3249
+
self.selected_call = Some(selected_call);
3250
3250
}
3251
3251
}
3252
3252
···
3454
3454
self.edits.insert(*line_end, format!("{indent}}}\n"));
3455
3455
indent += " ";
3456
3456
insertion = format!("{{\n{indent}{insertion}");
3457
3457
-
};
3457
3457
+
}
3458
3458
3459
3459
self.edits
3460
3460
.insert(insert_location.start, format!("{insertion}\n{indent}"));
···
3567
3567
3568
3568
fn visit_typed_assignment(&mut self, assignment: &'ast TypedAssignment) {
3569
3569
if let Pattern::Variable { name, .. } = &assignment.pattern {
3570
3570
-
self.name_generator.add_used_name(name.clone())
3571
3571
-
};
3570
3570
+
self.name_generator.add_used_name(name.clone());
3571
3571
+
}
3572
3572
ast::visit::visit_typed_assignment(self, assignment);
3573
3573
}
3574
3574
···
3591
3591
finally_kind,
3592
3592
);
3593
3593
return;
3594
3594
-
};
3594
3594
+
}
3595
3595
3596
3596
// Visiting a pipeline requires a bit of care, we don't want to extract
3597
3597
// intermediate steps as variables (those are function calls)!
···
3632
3632
}
3633
3633
3634
3634
self.at_position(ExtractVariablePosition::PipelineCall, |this| {
3635
3635
-
this.visit_typed_expr(finally)
3635
3635
+
this.visit_typed_expr(finally);
3636
3636
});
3637
3637
}
3638
3638
···
3801
3801
// variable inside the parenthesis where the call argument is located.
3802
3802
} else {
3803
3803
self.statement_before_selected_expression = self.latest_statement;
3804
3804
-
};
3804
3804
+
}
3805
3805
self.selected_expression = Some(ExtractedToVariable::Expression {
3806
3806
location: *location,
3807
3807
name: self.generate_candidate_name(expr.type_()),
···
4451
4451
arguments,
4452
4452
body,
4453
4453
return_annotation,
4454
4454
-
)
4454
4454
+
);
4455
4455
}
4456
4456
}
4457
4457
···
4973
4973
} else {
4974
4974
return Some(eco_format!("#({})", field_zeroes.iter().join(", ")));
4975
4975
}
4976
4976
-
};
4976
4976
+
}
4977
4977
4978
4978
let (module, name, _) = type_.named_type_information()?;
4979
4979
match (module.as_str(), name.as_str()) {
···
5022
5022
5023
5023
if already_seen_type {
5024
5024
return None;
5025
5025
-
};
5025
5025
+
}
5026
5026
5027
5027
let type_is_inside_current_module = &self.type_module == custom_type_module;
5028
5028
···
5112
5112
// Only proceed if we were able to construct every field successfully
5113
5113
if zero_params.len() < zero_constructor.parameters.len() {
5114
5114
return None;
5115
5115
-
};
5115
5115
+
}
5116
5116
5117
5117
let zero_constructor = if !type_is_inside_current_module {
5118
5118
// Type constructors from other modules need to be qualified appropriately,
···
5931
5931
self.edits.insert(
5932
5932
statement_location.end,
5933
5933
format!(" {{\n{patterns}\n{nesting}}}"),
5934
5934
-
)
5934
5934
+
);
5935
5935
}
5936
5936
}
5937
5937
···
6223
6223
self.selected_value = Some(PatternMatchedValue::Statement {
6224
6224
location: statement.location(),
6225
6225
type_: type_.clone(),
6226
6226
-
})
6226
6226
+
});
6227
6227
}
6228
6228
6229
6229
ast::Statement::Expression(_)
···
6476
6476
let location = PatternLocation::ListTail {
6477
6477
location: tail_location,
6478
6478
};
6479
6479
-
self.pattern_variable_under_cursor = Some((name, location, tail_type.clone()))
6479
6479
+
self.pattern_variable_under_cursor = Some((name, location, tail_type.clone()));
6480
6480
}
6481
6481
}
6482
6482
···
6742
6742
return_type,
6743
6743
previous_definition_end: self.last_visited_definition_end,
6744
6744
module: None,
6745
6745
-
})
6745
6745
+
});
6746
6746
}
6747
6747
}
6748
6748
}
···
6764
6764
return_type,
6765
6765
previous_definition_end: self.last_visited_definition_end,
6766
6766
module: Some(module),
6767
6767
-
})
6767
6767
+
});
6768
6768
}
6769
6769
}
6770
6770
}
···
6790
6790
if within(self.params.range, invalid_range) {
6791
6791
match extra_information {
6792
6792
Some(InvalidExpression::ModuleSelect { module_name, label }) => {
6793
6793
-
self.try_save_function_from_other_module(module_name, label, type_, None)
6793
6793
+
self.try_save_function_from_other_module(module_name, label, type_, None);
6794
6794
}
6795
6795
Some(InvalidExpression::UnknownVariable { name }) => {
6796
6796
-
self.try_save_function_to_generate(name, type_, None)
6796
6796
+
self.try_save_function_to_generate(name, type_, None);
6797
6797
}
6798
6798
None => {}
6799
6799
}
···
6814
6814
{
6815
6815
match extra_information {
6816
6816
InvalidExpression::ModuleSelect { module_name, label } => {
6817
6817
-
self.try_save_function_from_other_module(module_name, label, type_, None)
6817
6817
+
self.try_save_function_from_other_module(module_name, label, type_, None);
6818
6818
}
6819
6819
InvalidExpression::UnknownVariable { name } => {
6820
6820
-
self.try_save_function_to_generate(name, type_, None)
6820
6820
+
self.try_save_function_to_generate(name, type_, None);
6821
6821
}
6822
6822
}
6823
6823
}
···
7137
7137
builder = builder.changes(
7138
7138
self.params.text_document.uri.clone(),
7139
7139
current_module_edits.edits,
7140
7140
-
)
7140
7140
+
);
7141
7141
}
7142
7142
GenerateVariantEdits::GenerateInDifferentModule {
7143
7143
current_module_edits,
···
7155
7155
);
7156
7156
}
7157
7157
7158
7158
-
builder = builder.changes(variant_module_path, variant_module_edits.edits)
7158
7158
+
builder = builder.changes(variant_module_path, variant_module_edits.edits);
7159
7159
}
7160
7160
-
};
7160
7160
+
}
7161
7161
7162
7162
let mut action = Vec::with_capacity(1);
7163
7163
builder.push_to(&mut action);
···
7371
7371
current_module_edits.insert(insert_positions, new_text);
7372
7372
} else {
7373
7373
// We need to qualify the variant that triggered the code action!
7374
7374
-
current_module_edits.insert(variant_start, format!("{variant_module_name}."))
7374
7374
+
current_module_edits.insert(variant_start, format!("{variant_module_name}."));
7375
7375
}
7376
7376
}
7377
7377
}
···
7787
7787
// missing parentheses:
7788
7788
// `[1, 2] |> length` becomes `length([1, 2])`
7789
7789
PipelineAssignmentKind::FunctionCall => {
7790
7790
-
self.edits.insert(call.end, format!("({first_value_text})"))
7790
7790
+
self.edits.insert(call.end, format!("({first_value_text})"));
7791
7791
}
7792
7792
7793
7793
// When the piped value is inserted as the first argument there's two
···
7808
7808
// have to insert the value after the `echo` with no parentheses:
7809
7809
// `a |> echo` is rewritten as `echo a`.
7810
7810
PipelineAssignmentKind::Echo => {
7811
7811
-
self.edits.insert(call.end, format!(" {first_value_text}"))
7811
7811
+
self.edits.insert(call.end, format!(" {first_value_text}"));
7812
7812
}
7813
7813
}
7814
7814
···
8205
8205
// In all other cases we're piping something that is not the first
8206
8206
// argument so we just replace it with an `_`.
8207
8207
_ => self.edits.replace(arg.location, "_".into()),
8208
8208
-
};
8208
8208
+
}
8209
8209
8210
8210
// Finally we can add the argument that was removed as the first step
8211
8211
// of the newly defined pipeline.
···
8434
8434
}
8435
8435
8436
8436
StringInterpolation::SplitString { .. } => return vec![],
8437
8437
-
};
8437
8437
+
}
8438
8438
8439
8439
if self.string_literal_position == StringLiteralPosition::FirstPipelineStep {
8440
8440
self.edits.insert(string_location.end, " }".into());
···
8608
8608
// Do not suggest this code action if there's no ignored fields at all.
8609
8609
if positional.is_empty() && labelled.is_empty() {
8610
8610
return vec![];
8611
8611
-
};
8611
8611
+
}
8612
8612
8613
8613
// We add all the missing positional arguments before the first
8614
8614
// labelled one (and so after all the already existing positional ones).
···
8659
8659
// This way we also get rid of any comma separating the last argument
8660
8660
// and the spread to be removed.
8661
8661
self.edits
8662
8662
-
.delete(SrcSpan::new(delete_start, spread_location.end))
8662
8662
+
.delete(SrcSpan::new(delete_start, spread_location.end));
8663
8663
} else {
8664
8664
// Otherwise we just delete the spread.
8665
8665
-
self.edits.delete(spread_location)
8665
8665
+
self.edits.delete(spread_location);
8666
8666
}
8667
8667
8668
8668
let mut action = Vec::with_capacity(1);
···
8713
8713
last_argument_end,
8714
8714
spread_location: *spread_location,
8715
8715
});
8716
8716
-
};
8716
8716
+
}
8717
8717
8718
8718
ast::visit::visit_typed_pattern(self, pattern);
8719
8719
}
···
8757
8757
// the module
8758
8758
if !self.is_hovering_echo {
8759
8759
return vec![];
8760
8760
-
};
8760
8760
+
}
8761
8761
8762
8762
for span in self.echo_spans_to_delete {
8763
8763
self.edits.delete(span);
···
9072
9072
| TypedExpr::Invalid { .. } => {
9073
9073
self.selected_expression = Some(assignment.value.location());
9074
9074
}
9075
9075
-
};
9075
9075
+
}
9076
9076
ast::visit::visit_typed_assignment(self, assignment);
9077
9077
}
9078
9078
···
9089
9089
// To avoid wrapping the same expression in multiple, nested blocks.
9090
9090
if !matches!(clause.then, TypedExpr::Block { .. }) {
9091
9091
self.selected_expression = Some(clause.then.location());
9092
9092
-
};
9092
9092
+
}
9093
9093
9094
9094
ast::visit::visit_typed_clause(self, clause);
9095
9095
}
···
9157
9157
} else if operator.is_float_operator() && left.is_int() && right.is_int() {
9158
9158
self.fix = operator
9159
9159
.int_equivalent()
9160
9160
-
.map(|fix| (operator_location, fix))
9160
9160
+
.map(|fix| (operator_location, fix));
9161
9161
} else if operator == ast::BinOp::AddInt && left.is_string() && right.is_string() {
9162
9162
-
self.fix = Some((operator_location, ast::BinOp::Concatenate))
9162
9162
+
self.fix = Some((operator_location, ast::BinOp::Concatenate));
9163
9163
}
9164
9164
}
9165
9165
}
···
9442
9442
self.edits.delete(SrcSpan {
9443
9443
start: location.start,
9444
9444
end: location.end + 1,
9445
9445
-
})
9445
9445
+
});
9446
9446
} else {
9447
9447
-
self.edits.delete(*location)
9447
9447
+
self.edits.delete(*location);
9448
9448
}
9449
9449
}
9450
9450
···
9500
9500
self.edits.delete(SrcSpan {
9501
9501
start: previous_value.end,
9502
9502
end: location.end,
9503
9503
-
})
9503
9503
+
});
9504
9504
}
9505
9505
9506
9506
// In all other cases it means that this is the only
···
9613
9613
ast::Statement::Use(_)
9614
9614
| ast::Statement::Assert(_)
9615
9615
| ast::Statement::Assignment(_) => {
9616
9616
-
ast::visit::visit_typed_expr_block(self, location, statements)
9616
9616
+
ast::visit::visit_typed_expr_block(self, location, statements);
9617
9617
}
9618
9618
9619
9619
ast::Statement::Expression(expr) => match expr {
···
9707
9707
self.opaque_span = Some(SrcSpan {
9708
9708
start: custom_type.location.start,
9709
9709
end: custom_type.location.start + 7,
9710
9710
-
})
9710
9710
+
});
9711
9711
}
9712
9712
}
9713
9713
}
···
9925
9925
// When it's a list literal, we remove the surrounding brackets.
9926
9926
let len = trimmed_contents.len();
9927
9927
if let Some(slice) = new_content.trim().get(1..(len - 1)) {
9928
9928
-
new_content = slice.to_string()
9929
9929
-
};
9928
9928
+
new_content = slice.to_string();
9929
9929
+
}
9930
9930
9931
9931
*tail_location
9932
9932
}
···
9984
9984
let mut pattern_code = code_at(self.module, pattern_location).to_string();
9985
9985
if !references_to_matched_variable.is_empty() {
9986
9986
pattern_code = format!("{pattern_code} as {}", matched_variable.name());
9987
9987
-
};
9987
9987
+
}
9988
9988
pattern_with_variable(pattern_code)
9989
9989
})
9990
9990
.join(" | ");
···
9995
9995
let mut outer_code = code_at(self.module, outer.location()).to_string();
9996
9996
let mut inner_code = code_at(self.module, inner.location()).to_string();
9997
9997
if ast::BinOp::And.precedence() > outer.precedence() {
9998
9998
-
outer_code = format!("{{ {outer_code} }}")
9998
9998
+
outer_code = format!("{{ {outer_code} }}");
9999
9999
}
10000
10000
if ast::BinOp::And.precedence() > inner.precedence() {
10001
10001
-
inner_code = format!("{{ {inner_code} }}")
10001
10001
+
inner_code = format!("{{ {inner_code} }}");
10002
10002
}
10003
10003
format!(" if {outer_code} && {inner_code}")
10004
10004
}
···
10123
10123
// We're done, there's no need to keep exploring as we know the
10124
10124
// cursor is over this pattern and it can't be over any other one!
10125
10125
return;
10126
10126
-
};
10126
10126
+
}
10127
10127
10128
10128
ast::visit::visit_typed_clause(self, clause);
10129
10129
}
···
10328
10328
// // we want the entire branch to be deleted!
10329
10329
// }
10330
10330
// ```
10331
10331
-
self.clauses_to_delete.push(clause.location())
10331
10331
+
self.clauses_to_delete.push(clause.location());
10332
10332
} else {
10333
10333
// If only some of the variants are unreachable but not all
10334
10334
// we want to delete just those.
···
10476
10476
self.edits.insert(call_argument.location.end, ":".into());
10477
10477
} else {
10478
10478
self.edits
10479
10479
-
.insert(call_argument.location.start, format!("{label}: "))
10479
10479
+
.insert(call_argument.location.start, format!("{label}: "));
10480
10480
}
10481
10481
}
10482
10482
···
10559
10559
location: argument.location,
10560
10560
omitted_label: label,
10561
10561
can_use_shorthand_syntax,
10562
10562
-
})
10562
10562
+
});
10563
10563
}
10564
10564
self.arguments_and_omitted_labels = Some(omitted_labels);
10565
10565
}
···
10816
10816
extracted.parameters,
10817
10817
statements.last().type_(),
10818
10818
end,
10819
10819
-
)
10819
10819
+
);
10820
10820
}
10821
10821
ExtractedValue::Expression(TypedExpr::Fn {
10822
10822
type_,
···
10836
10836
arguments,
10837
10837
return_type,
10838
10838
end,
10839
10839
-
)
10839
10839
+
);
10840
10840
} else if arguments.len() == 1 {
10841
10841
self.extract_anonymous_function_with_capture_hole(
10842
10842
*full_location,
···
10845
10845
extracted.parameters,
10846
10846
return_type,
10847
10847
end,
10848
10848
-
)
10848
10848
+
);
10849
10849
} else {
10850
10850
self.extract_anonymous_function_body(
10851
10851
location,
···
10853
10853
extracted.parameters,
10854
10854
return_type,
10855
10855
end,
10856
10856
-
)
10856
10856
+
);
10857
10857
}
10858
10858
}
10859
10859
ExtractedValue::Expression(expression) => {
···
10873
10873
extracted.parameters,
10874
10874
expression_type,
10875
10875
end,
10876
10876
-
)
10876
10876
+
);
10877
10877
}
10878
10878
ExtractedValue::Statements {
10879
10879
location,
···
10894
10894
extracted.parameters,
10895
10895
extracted.returned_variables,
10896
10896
end,
10897
10897
-
)
10898
10898
-
};
10897
10897
+
);
10898
10898
+
}
10899
10899
}
10900
10900
10901
10901
ExtractedValue::Use {
···
11753
11753
&& position_within(self.params.range.end, final_step_range)
11754
11754
{
11755
11755
extracted_function.try_add_pipeline_step(finally.type_(), finally.location());
11756
11756
-
};
11756
11756
+
}
11757
11757
11758
11758
self.visit_typed_expr(finally);
11759
11759
self.previous_pipeline_assignment_type = None;
···
11776
11776
}));
11777
11777
}
11778
11778
Some(extracted_function) => {
11779
11779
-
extracted_function.try_add_pipeline_step(assignment.type_(), assignment.location)
11779
11779
+
extracted_function.try_add_pipeline_step(assignment.type_(), assignment.location);
11780
11780
}
11781
11781
}
11782
11782
ast::visit::visit_typed_pipeline_assignment(self, assignment);
···
12141
12141
}
12142
12142
12143
12143
if let result @ Some(_) = self.select_mergeable_branches(clauses) {
12144
12144
-
self.patterns_to_merge = result
12144
12144
+
self.patterns_to_merge = result;
12145
12145
}
12146
12146
12147
12147
// We still need to visit the case expression in case we want to apply
···
12359
12359
self.hovered_hole = Some(HoveredHole {
12360
12360
type_,
12361
12361
location: *location,
12362
12362
-
})
12362
12362
+
});
12363
12363
}
12364
12364
}
12365
12365
}
···
12689
12689
outer_function_body_start: outer_body.start,
12690
12690
inner_function: *call_location,
12691
12691
inner_function_arguments_start: *arguments_start,
12692
12692
-
})
12692
12692
+
});
12693
12693
}
12694
12694
}
12695
12695
···
12718
12718
arguments,
12719
12719
body,
12720
12720
return_annotation,
12721
12721
-
)
12721
12721
+
);
12722
12722
}
12723
12723
}
12724
12724
···
580
580
.config
581
581
.dev_dependencies
582
582
.keys(),
583
583
-
)
583
583
+
);
584
584
}
585
585
586
586
let already_imported: std::collections::HashSet<EcoString> =
···
742
742
&cursor_surroundings,
743
743
TypeCompletionContext::UnqualifiedType,
744
744
CompletionKind::ImportedModule,
745
745
-
))
745
745
+
));
746
746
}
747
747
}
748
748
}
···
844
844
if !cursor_surroundings.surrounding_text.is_empty() {
845
845
for keyword in ["panic", "todo", "echo"] {
846
846
if keyword.starts_with(cursor_surroundings.surrounding_text.as_str()) {
847
847
-
completions.push(self.keyword_completion(keyword, &cursor_surroundings))
847
847
+
completions.push(self.keyword_completion(keyword, &cursor_surroundings));
848
848
}
849
849
}
850
850
}
···
896
896
match match_type(&self.expected_type, &type_) {
897
897
TypeMatch::Incompatible => return,
898
898
TypeMatch::Matching | TypeMatch::Unknown => (),
899
899
-
};
899
899
+
}
900
900
901
901
let label = label.to_string();
902
902
let sort_text = Some(sort_text(
···
1011
1011
value,
1012
1012
&cursor_surroundings,
1013
1013
CompletionKind::ImportedModule,
1014
1014
-
))
1014
1014
+
));
1015
1015
}
1016
1016
}
1017
1017
}
···
144
144
self.edits.push(TextEdit {
145
145
range: src_span_to_lsp_range(location, self.line_numbers),
146
146
new_text,
147
147
-
})
147
147
+
});
148
148
}
149
149
150
150
pub fn insert(&mut self, at: u32, new_text: String) {
151
151
-
self.replace(SrcSpan { start: at, end: at }, new_text)
151
151
+
self.replace(SrcSpan { start: at, end: at }, new_text);
152
152
}
153
153
154
154
pub fn delete(&mut self, location: SrcSpan) {
155
155
-
self.replace(location, "".to_string())
155
155
+
self.replace(location, "".to_string());
156
156
}
157
157
158
158
fn delete_range(&mut self, range: Range) {
159
159
self.edits.push(TextEdit {
160
160
range,
161
161
new_text: "".into(),
162
162
-
})
162
162
+
});
163
163
}
164
164
}
165
165
···
50
50
self.connection
51
51
.sender
52
52
.send(lsp_server::Message::Notification(notification))
53
53
-
.expect("send_work_done_notification send")
53
53
+
.expect("send_work_done_notification send");
54
54
}
55
55
}
56
56
···
771
771
}
772
772
773
773
DefinitionLocation::Regular { .. } | DefinitionLocation::Alternative { .. } => (),
774
774
-
};
774
774
+
}
775
775
}
776
776
777
777
pub fn find_in_module(mut self, module: &TypedModule) -> HashSet<VariableReference> {
···
979
979
// Handle the suffix in alternative pattern: "prefix" <> name | "other_prefix" <> name
980
980
match right_side_assignment {
981
981
AssignName::Variable(name) => {
982
982
-
self.register_alternative_definition(name, right_location)
982
982
+
self.register_alternative_definition(name, right_location);
983
983
}
984
984
AssignName::Discard(_) => {}
985
985
}
···
1029
1029
if custom_type.full_location().contains_span(self.location) {
1030
1030
for (location, name) in custom_type.parameters.iter() {
1031
1031
if name == self.name {
1032
1032
-
self.references.push(*location)
1032
1032
+
self.references.push(*location);
1033
1033
}
1034
1034
}
1035
1035
ast::visit::visit_typed_custom_type(self, custom_type);
···
1046
1046
if type_alias.location.contains_span(self.location) {
1047
1047
for (location, name) in type_alias.parameters.iter() {
1048
1048
if name == self.name {
1049
1049
-
self.references.push(*location)
1049
1049
+
self.references.push(*location);
1050
1050
}
1051
1051
}
1052
1052
ast::visit::visit_typed_type_alias(self, type_alias);
···
91
91
92
92
match kind {
93
93
VariableReferenceKind::Variable => {
94
94
-
edits.replace(definition_location, params.new_name.clone())
94
94
+
edits.replace(definition_location, params.new_name.clone());
95
95
}
96
96
VariableReferenceKind::LabelShorthand => {
97
97
-
edits.insert(definition_location.end, format!(" {}", params.new_name))
97
97
+
edits.insert(definition_location.end, format!(" {}", params.new_name));
98
98
}
99
99
}
100
100
101
101
for reference in references {
102
102
match reference.kind {
103
103
VariableReferenceKind::Variable => {
104
104
-
edits.replace(reference.location, params.new_name.clone())
104
104
+
edits.replace(reference.location, params.new_name.clone());
105
105
}
106
106
VariableReferenceKind::LabelShorthand => {
107
107
-
edits.insert(reference.location.end, format!(" {}", params.new_name))
107
107
+
edits.insert(reference.location.end, format!(" {}", params.new_name));
108
108
}
109
109
}
110
110
}
···
327
327
// would break that, so we expand the shorthand and keep the original
328
328
// name as the value: `wibble:` becomes `new_name: wibble`.
329
329
LabelSyntax::Shorthand => {
330
330
-
edits.replace(reference.location, format!("{new_name}: {label}"))
330
330
+
edits.replace(reference.location, format!("{new_name}: {label}"));
331
331
}
332
332
LabelSyntax::Longhand => edits.replace(reference.location, new_name.to_string()),
333
333
}
···
365
365
match reference.kind {
366
366
ReferenceKind::Qualified { .. } => {}
367
367
ReferenceKind::Unqualified | ReferenceKind::Alias => {
368
368
-
edits.replace(reference.location, params.new_name.clone())
368
368
+
edits.replace(reference.location, params.new_name.clone());
369
369
}
370
370
ReferenceKind::Import(alias_location) => {
371
371
// If old name is equal to original name, we can just remove
···
495
495
if params.new_name == original_module_name {
496
496
edits.delete(SrcSpan::new(alias_location.start - 1, alias_location.end));
497
497
} else {
498
498
-
edits.replace(*alias_location, format!("as {}", params.new_name))
498
498
+
edits.replace(*alias_location, format!("as {}", params.new_name));
499
499
}
500
500
}
501
501
ModuleNameReference::ModuleSelect(location)
···
532
532
let references = FindTypeVariableReferences::find_in_module(&module.ast, location, &name);
533
533
534
534
for reference in references {
535
535
-
edits.replace(reference, params.new_name.clone())
535
535
+
edits.replace(reference, params.new_name.clone());
536
536
}
537
537
538
538
RenameOutcome::Renamed {
···
604
604
// to change.
605
605
ModuleNameReference::AliasedModuleSelect(_) => {}
606
606
ModuleNameReference::ModuleSelect(location) => {
607
607
-
edits.replace(*location, last_component_of_new_name.clone())
607
607
+
edits.replace(*location, last_component_of_new_name.clone());
608
608
}
609
609
}
610
610
}
···
137
137
self.connection
138
138
.sender
139
139
.send(lsp_server::Message::Response(response))
140
140
-
.expect("channel send LSP response")
140
140
+
.expect("channel send LSP response");
141
141
}
142
142
143
143
fn handle_notification(&mut self, notification: Notification) {
···
521
521
let mut feedback = self.cache_file_in_memory(path.clone(), text);
522
522
if let Ok(Some(project)) = self.router.project_for_path(path.clone()) {
523
523
feedback.append_feedback(project.feedback.open_file(path));
524
524
-
};
524
524
+
}
525
525
feedback
526
526
}
527
527
···
529
529
let mut feedback = self.discard_in_memory_cache(path.clone());
530
530
if let Ok(Some(project)) = self.router.project_for_path(path.clone()) {
531
531
feedback.append_feedback(project.feedback.close_file(&path));
532
532
-
};
532
532
+
}
533
533
feedback
534
534
}
535
535
}