Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Store information in `TypedExpr::Invalid`

+95 -73
+1
compiler-core/src/analyse.rs
··· 628 628 start: body_location.end, 629 629 end: body_location.end, 630 630 }, 631 + extra_information: None, 631 632 })); 632 633 let implementations = Implementations::supporting_all(); 633 634 (
+1 -1
compiler-core/src/ast.rs
··· 6 6 mod tests; 7 7 pub mod visit; 8 8 9 - pub use self::typed::TypedExpr; 9 + pub use self::typed::{InvalidExpression, TypedExpr}; 10 10 pub use self::untyped::{FunctionLiteralKind, UntypedExpr}; 11 11 12 12 pub use self::constant::{Constant, TypedConstant, UntypedConstant};
+12
compiler-core/src/ast/typed.rs
··· 188 188 Invalid { 189 189 location: SrcSpan, 190 190 type_: Arc<Type>, 191 + /// Extra information about the invalid expression, useful for providing 192 + /// addition help or information, such as code actions to fix invalid 193 + /// states. 194 + extra_information: Option<InvalidExpression>, 191 195 }, 192 196 } 193 197 ··· 1162 1166 } 1163 1167 } 1164 1168 } 1169 + 1170 + #[derive(Debug, Clone, PartialEq, Eq)] 1171 + pub enum InvalidExpression { 1172 + ModuleSelect { 1173 + module_name: EcoString, 1174 + label: EcoString, 1175 + }, 1176 + }
+19 -6
compiler-core/src/ast/visit.rs
··· 40 40 41 41 use crate::{ 42 42 analyse::Inferred, 43 - ast::{BitArraySize, TypedBitArraySize}, 43 + ast::{BitArraySize, TypedBitArraySize, typed::InvalidExpression}, 44 44 exhaustiveness::CompiledCase, 45 45 type_::{ 46 46 ModuleValueConstructor, PatternConstructor, TypedCallArg, ValueConstructor, ··· 335 335 visit_typed_expr_negate_int(self, location, value) 336 336 } 337 337 338 - fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, type_: &'ast Arc<Type>) { 339 - visit_typed_expr_invalid(self, location, type_); 338 + fn visit_typed_expr_invalid( 339 + &mut self, 340 + location: &'ast SrcSpan, 341 + type_: &'ast Arc<Type>, 342 + extra_information: &'ast Option<InvalidExpression>, 343 + ) { 344 + visit_typed_expr_invalid(self, location, type_, extra_information); 340 345 } 341 346 342 347 fn visit_typed_statement(&mut self, stmt: &'ast TypedStatement) { ··· 903 908 v.visit_typed_expr_negate_bool(location, value) 904 909 } 905 910 TypedExpr::NegateInt { location, value } => v.visit_typed_expr_negate_int(location, value), 906 - TypedExpr::Invalid { location, type_ } => v.visit_typed_expr_invalid(location, type_), 911 + TypedExpr::Invalid { 912 + location, 913 + type_, 914 + extra_information, 915 + } => v.visit_typed_expr_invalid(location, type_, extra_information), 907 916 TypedExpr::Echo { 908 917 location, 909 918 expression, ··· 1843 1852 { 1844 1853 } 1845 1854 1846 - pub fn visit_typed_expr_invalid<'a, V>(_v: &mut V, _location: &'a SrcSpan, _type_: &'a Arc<Type>) 1847 - where 1855 + pub fn visit_typed_expr_invalid<'a, V>( 1856 + _v: &mut V, 1857 + _location: &'a SrcSpan, 1858 + _type_: &'a Arc<Type>, 1859 + _extra_information: &'a Option<InvalidExpression>, 1860 + ) where 1848 1861 V: Visit<'a> + ?Sized, 1849 1862 { 1850 1863 }
+41 -40
compiler-core/src/language_server/code_action.rs
··· 4 4 Error, STDLIB_PACKAGE_NAME, analyse, 5 5 ast::{ 6 6 self, ArgNames, AssignName, AssignmentKind, BitArraySegmentTruncation, BoundVariable, 7 - CallArg, CustomType, FunctionLiteralKind, ImplicitCallArgOrigin, Import, PIPE_PRECEDENCE, 8 - Pattern, PatternUnusedArguments, PipelineAssignmentKind, Publicity, RecordConstructor, 9 - SrcSpan, TodoKind, TypedArg, TypedAssignment, TypedClauseGuard, TypedExpr, 10 - TypedModuleConstant, TypedPattern, TypedPipelineAssignment, TypedRecordConstructor, 11 - TypedStatement, TypedUse, visit::Visit as _, 7 + CallArg, CustomType, FunctionLiteralKind, ImplicitCallArgOrigin, Import, InvalidExpression, 8 + PIPE_PRECEDENCE, Pattern, PatternUnusedArguments, PipelineAssignmentKind, Publicity, 9 + RecordConstructor, SrcSpan, TodoKind, TypedArg, TypedAssignment, TypedClauseGuard, 10 + TypedExpr, TypedModuleConstant, TypedPattern, TypedPipelineAssignment, 11 + TypedRecordConstructor, TypedStatement, TypedUse, visit::Visit as _, 12 12 }, 13 13 build::{Located, Module}, 14 14 config::PackageConfig, ··· 3006 3006 3007 3007 // We don't want to offer the action if the cursor is over some invalid 3008 3008 // piece of code. 3009 - fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, _type_: &'ast Arc<Type>) { 3009 + fn visit_typed_expr_invalid( 3010 + &mut self, 3011 + location: &'ast SrcSpan, 3012 + _type_: &'ast Arc<Type>, 3013 + _extra_information: &'ast Option<InvalidExpression>, 3014 + ) { 3010 3015 let invalid_range = self.edits.src_span_to_lsp_range(*location); 3011 3016 if within(self.params.range, invalid_range) { 3012 3017 self.selected_expression = None; ··· 5121 5126 ast::visit::visit_typed_function(self, fun); 5122 5127 } 5123 5128 5124 - fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, type_: &'ast Arc<Type>) { 5125 - let invalid_range = self.edits.src_span_to_lsp_range(*location); 5126 - if within(self.params.range, invalid_range) { 5127 - self.try_save_function_to_generate(*location, type_, None); 5128 - } 5129 - 5130 - ast::visit::visit_typed_expr_invalid(self, location, type_); 5131 - } 5132 - 5133 - fn visit_typed_expr_module_select( 5129 + fn visit_typed_expr_invalid( 5134 5130 &mut self, 5135 - _location: &'ast SrcSpan, 5136 - _field_start: &'ast u32, 5131 + location: &'ast SrcSpan, 5137 5132 type_: &'ast Arc<Type>, 5138 - label: &'ast EcoString, 5139 - module_name: &'ast EcoString, 5140 - _module_alias: &'ast EcoString, 5141 - constructor: &'ast ModuleValueConstructor, 5133 + extra_information: &'ast Option<InvalidExpression>, 5142 5134 ) { 5143 - match constructor { 5144 - // Invalid module selects leave the `name` field blank 5145 - ModuleValueConstructor::Fn { name, .. } if name.is_empty() => { 5146 - self.try_save_function_from_other_module(module_name, label, type_, None); 5135 + let invalid_range = self.edits.src_span_to_lsp_range(*location); 5136 + if within(self.params.range, invalid_range) { 5137 + match extra_information { 5138 + Some(InvalidExpression::ModuleSelect { module_name, label }) => { 5139 + self.try_save_function_from_other_module(module_name, label, type_, None) 5140 + } 5141 + None => self.try_save_function_to_generate(*location, type_, None), 5147 5142 } 5148 - ModuleValueConstructor::Fn { .. } 5149 - | ModuleValueConstructor::Record { .. } 5150 - | ModuleValueConstructor::Constant { .. } => {} 5151 5143 } 5144 + 5145 + ast::visit::visit_typed_expr_invalid(self, location, type_, extra_information); 5152 5146 } 5153 5147 5154 5148 fn visit_typed_expr_call( ··· 5168 5162 } 5169 5163 5170 5164 match fun { 5171 - TypedExpr::Invalid { type_, location } => { 5172 - return self.try_save_function_to_generate(*location, type_, Some(arguments)); 5173 - } 5174 - TypedExpr::ModuleSelect { 5175 - module_name, 5176 - label, 5165 + TypedExpr::Invalid { 5177 5166 type_, 5178 - constructor: ModuleValueConstructor::Fn { name, .. }, 5179 - .. 5180 - } if name.is_empty() => { 5167 + extra_information: Some(InvalidExpression::ModuleSelect { module_name, label }), 5168 + location: _, 5169 + } => { 5181 5170 return self.try_save_function_from_other_module( 5182 5171 module_name, 5183 5172 label, 5184 5173 type_, 5185 5174 Some(arguments), 5186 5175 ); 5176 + } 5177 + TypedExpr::Invalid { 5178 + type_, 5179 + location, 5180 + extra_information: _, 5181 + } => { 5182 + return self.try_save_function_to_generate(*location, type_, Some(arguments)); 5187 5183 } 5188 5184 _ => {} 5189 5185 } ··· 5494 5490 where 5495 5491 IO: FileSystemReader + FileSystemWriter + BeamCompiler + CommandExecutor + Clone, 5496 5492 { 5497 - fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, type_: &'ast Arc<Type>) { 5493 + fn visit_typed_expr_invalid( 5494 + &mut self, 5495 + location: &'ast SrcSpan, 5496 + type_: &'ast Arc<Type>, 5497 + extra_information: &'ast Option<InvalidExpression>, 5498 + ) { 5498 5499 let invalid_range = src_span_to_lsp_range(*location, self.line_numbers); 5499 5500 if within(self.params.range, invalid_range) { 5500 5501 self.try_save_variant_to_generate(*location, type_, None); 5501 5502 } 5502 - ast::visit::visit_typed_expr_invalid(self, location, type_); 5503 + ast::visit::visit_typed_expr_invalid(self, location, type_, extra_information); 5503 5504 } 5504 5505 5505 5506 fn visit_typed_expr_call(
+18 -26
compiler-core/src/type_/expression.rs
··· 5 5 ast::{ 6 6 Arg, Assert, Assignment, AssignmentKind, BinOp, BitArrayOption, BitArraySegment, 7 7 CAPTURE_VARIABLE, CallArg, Clause, ClauseGuard, Constant, FunctionLiteralKind, HasLocation, 8 - ImplicitCallArgOrigin, Layer, RECORD_UPDATE_VARIABLE, RecordBeingUpdated, SrcSpan, 9 - Statement, TodoKind, TypeAst, TypedArg, TypedAssert, TypedAssignment, TypedClause, 10 - TypedClauseGuard, TypedConstant, TypedExpr, TypedMultiPattern, TypedStatement, 11 - USE_ASSIGNMENT_VARIABLE, UntypedArg, UntypedAssert, UntypedAssignment, UntypedClause, 12 - UntypedClauseGuard, UntypedConstant, UntypedConstantBitArraySegment, UntypedExpr, 13 - UntypedExprBitArraySegment, UntypedMultiPattern, UntypedStatement, UntypedUse, 14 - UntypedUseAssignment, Use, UseAssignment, 8 + ImplicitCallArgOrigin, InvalidExpression, Layer, RECORD_UPDATE_VARIABLE, 9 + RecordBeingUpdated, SrcSpan, Statement, TodoKind, TypeAst, TypedArg, TypedAssert, 10 + TypedAssignment, TypedClause, TypedClauseGuard, TypedConstant, TypedExpr, 11 + TypedMultiPattern, TypedStatement, USE_ASSIGNMENT_VARIABLE, UntypedArg, UntypedAssert, 12 + UntypedAssignment, UntypedClause, UntypedClauseGuard, UntypedConstant, 13 + UntypedConstantBitArraySegment, UntypedExpr, UntypedExprBitArraySegment, 14 + UntypedMultiPattern, UntypedStatement, UntypedUse, UntypedUseAssignment, Use, 15 + UseAssignment, 15 16 }, 16 17 build::Target, 17 18 exhaustiveness::{self, CompileCaseResult, CompiledCase, Reachability}, ··· 728 729 TypedExpr::Invalid { 729 730 location, 730 731 type_: self.new_unbound_var(), 732 + extra_information: None, 731 733 } 732 734 } 733 735 ··· 1420 1422 } 1421 1423 } 1422 1424 // If module access failed because the module exists but that module does not export 1423 - // the referenced value, we return a `TypedExpr::ModuleSelect` instead of 1424 - // `TypedExpr::Invalid`, so that we have information about the attempted module select 1425 - // and can use it, for example, in the "Generate function" code action to support other 1426 - // modules. 1425 + // the referenced value, we return extra information about the invalid module select, 1426 + // so that we have information about the attempted module select and can use it, for 1427 + // example, in the "Generate function" code action to support other modules. 1427 1428 ( 1428 1429 _, 1429 1430 Some(( ··· 1446 1447 type_with_same_name, 1447 1448 context, 1448 1449 }); 1449 - TypedExpr::ModuleSelect { 1450 + TypedExpr::Invalid { 1450 1451 location, 1451 - field_start: label_location.start, 1452 1452 type_: self.new_unbound_var(), 1453 - label, 1454 - module_alias: module_name.clone(), 1455 - module_name, 1456 - constructor: ModuleValueConstructor::Fn { 1457 - location, 1458 - module: "".into(), 1459 - name: "".into(), 1460 - external_erlang: None, 1461 - external_javascript: None, 1462 - field_map: None, 1463 - documentation: None, 1464 - purity: Purity::Unknown, 1465 - }, 1453 + extra_information: Some(InvalidExpression::ModuleSelect { module_name, label }), 1466 1454 } 1467 1455 } 1468 1456 // If module access failed for some other reason, and no local variable shadows the ··· 1472 1460 TypedExpr::Invalid { 1473 1461 location, 1474 1462 type_: self.new_unbound_var(), 1463 + extra_information: None, 1475 1464 } 1476 1465 } 1477 1466 // In any other case use the record access for the error ··· 1493 1482 Err(_) => TypedExpr::Invalid { 1494 1483 location, 1495 1484 type_: self.new_unbound_var(), 1485 + extra_information: None, 1496 1486 }, 1497 1487 } 1498 1488 } ··· 4410 4400 value: TypedExpr::Invalid { 4411 4401 location, 4412 4402 type_: self.new_unbound_var(), 4403 + extra_information: None, 4413 4404 }, 4414 4405 implicit, 4415 4406 location, ··· 4590 4581 end: body.last().location().end, 4591 4582 }, 4592 4583 type_: body_typer.new_unbound_var(), 4584 + extra_information: None, 4593 4585 })) 4594 4586 }; 4595 4587
+3
compiler-core/src/type_/pipe.rs
··· 63 63 TypedExpr::Invalid { 64 64 location: first_location, 65 65 type_: expr_typer.new_unbound_var(), 66 + extra_information: None, 66 67 } 67 68 } 68 69 }; ··· 149 150 TypedExpr::Invalid { 150 151 location, 151 152 type_: self.expr_typer.new_unbound_var(), 153 + extra_information: None, 152 154 } 153 155 } 154 156 }; ··· 359 361 TypedExpr::Invalid { 360 362 location: function_location, 361 363 type_: self.expr_typer.new_unbound_var(), 364 + extra_information: None, 362 365 } 363 366 } 364 367 });