From 0657e21fdb265fbb58f7cd5f634fb1634517aaf6 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 28 Jun 2021 15:54:19 +0200 Subject: [PATCH] can make empty list in editor, panic on type tooltip --- compiler/module/src/symbol.rs | 4 ++ compiler/mono/src/alias_analysis.rs | 4 +- compiler/types/src/pretty_print.rs | 2 + editor/src/editor/markup/nodes.rs | 2 + editor/src/editor/mvc/ed_model.rs | 1 - editor/src/editor/mvc/ed_update.rs | 28 ++++++++- editor/src/editor/mvc/list_update.rs | 88 ++++++++++++++++++++++++++++ editor/src/editor/mvc/mod.rs | 1 + editor/src/lang/ast.rs | 43 ++++++++++---- editor/tests/solve_expr2.rs | 4 +- 10 files changed, 160 insertions(+), 17 deletions(-) create mode 100644 editor/src/editor/mvc/list_update.rs diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index d107bdffe4..b482200b32 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -66,6 +66,10 @@ impl Symbol { } pub fn ident_string(self, interns: &Interns) -> &InlinableString { + + dbg!(&self.module_id()); + dbg!(interns); + println!("DONE"); let ident_ids = interns .all_ident_ids .get(&self.module_id()) diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 5a59917ed8..beb8c79917 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -166,9 +166,9 @@ where p.build()? }; - if DEBUG { + /*if DEBUG { eprintln!("{}", program.to_source_string()); - } + }*/ morphic_lib::solve(program) } diff --git a/compiler/types/src/pretty_print.rs b/compiler/types/src/pretty_print.rs index 8df08669d1..98ab8c65b2 100644 --- a/compiler/types/src/pretty_print.rs +++ b/compiler/types/src/pretty_print.rs @@ -356,6 +356,8 @@ fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, par fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String, parens: Parens) { use crate::subs::FlatType::*; + println!("REMOVE ME"); + match flat_type { Apply(symbol, args) => write_apply(env, symbol, args, subs, buf, parens), EmptyRecord => buf.push_str(EMPTY_RECORD), diff --git a/editor/src/editor/markup/nodes.rs b/editor/src/editor/markup/nodes.rs index 2d09f21ed6..84864225b2 100644 --- a/editor/src/editor/markup/nodes.rs +++ b/editor/src/editor/markup/nodes.rs @@ -143,6 +143,8 @@ fn get_string<'a>(env: &Env<'a>, pool_str: &PoolStr) -> String { pub const BLANK_PLACEHOLDER: &str = " "; pub const LEFT_ACCOLADE: &str = "{ "; pub const RIGHT_ACCOLADE: &str = " }"; +pub const LEFT_SQUARE_BR: &str = "[ "; +pub const RIGHT_SQUARE_BR: &str = " ]"; pub const COLON: &str = ": "; pub const STRING_QUOTES: &str = "\"\""; diff --git a/editor/src/editor/mvc/ed_model.rs b/editor/src/editor/mvc/ed_model.rs index 64b36ecf7e..64a264a7a9 100644 --- a/editor/src/editor/mvc/ed_model.rs +++ b/editor/src/editor/mvc/ed_model.rs @@ -196,7 +196,6 @@ pub mod test_ed_model { let file_path = Path::new(""); let dep_idents = IdentIds::exposed_builtins(8); - let exposed_ident_ids = IdentIds::default(); let mod_id = ed_model_refs.module_ids.get_or_insert(&"ModId123".into()); diff --git a/editor/src/editor/mvc/ed_update.rs b/editor/src/editor/mvc/ed_update.rs index 5562261a69..7199035865 100644 --- a/editor/src/editor/mvc/ed_update.rs +++ b/editor/src/editor/mvc/ed_update.rs @@ -21,6 +21,7 @@ use crate::editor::mvc::record_update::update_record_field; use crate::editor::mvc::string_update::start_new_string; use crate::editor::mvc::string_update::update_small_string; use crate::editor::mvc::string_update::update_string; +use crate::editor::mvc::list_update::start_new_list; use crate::editor::slow_pool::MarkNodeId; use crate::editor::slow_pool::SlowPool; use crate::editor::syntax_highlight::HighlightStyle; @@ -44,7 +45,7 @@ use bumpalo::Bump; use roc_can::expected::Expected; use roc_collections::all::MutMap; use roc_module::ident::Lowercase; -use roc_module::symbol::Symbol; +use roc_module::symbol::{Interns, Symbol}; use roc_region::all::Region; use roc_types::solved_types::Solved; use roc_types::subs::{Subs, Variable}; @@ -264,8 +265,13 @@ impl<'a> EdModel<'a> { let content = subs.get(var).content; + let interns = Interns { + module_ids: *self.module.env.module_ids, + all_ident_ids: self.module.env.dep_idents, + }; + PoolStr::new( - &content_to_string(content, &subs, self.module.env.home, &Default::default()), + &content_to_string(content, &subs, self.module.env.home, &interns), self.module.env.pool, ) } @@ -581,6 +587,10 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult '0'..='9' => { start_new_int(ed_model, ch)? } + '[' => { + // this can also be a tag union or become a set, assuming list for now + start_new_list(ed_model)? + } _ => InputOutcome::Ignored } } else if let Some(prev_mark_node_id) = prev_mark_node_id_opt{ @@ -1724,6 +1734,20 @@ pub mod test_ed_update { Ok(()) } + #[test] + fn test_ctrl_shift_up_list() -> Result<(), String> { + assert_ctrl_shift_up(&["[ ┃ ]"], &["┃❮[ ]❯"])?; + assert_ctrl_shift_up(&["[┃ ]"], &["┃❮[ ]❯"])?; + assert_ctrl_shift_up(&["[ ┃]"], &["┃❮[ ]❯"])?; + assert_ctrl_shift_up(&["┃[ ]"], &["┃❮[ ]❯"])?; + assert_ctrl_shift_up(&["[ ]┃"], &["┃❮[ ]❯"])?; + + assert_ctrl_shift_up_repeat(&["[ ┃ ]"], &["┃❮[ ]❯"], 4)?; + + //TODO non-empty list + Ok(()) + } + // Create ed_model from pre_lines DSL, do handle_new_char() with new_char_seq, select current Expr2, // check if generated tooltips match expected_tooltips. pub fn assert_type_tooltips_seq( diff --git a/editor/src/editor/mvc/list_update.rs b/editor/src/editor/mvc/list_update.rs new file mode 100644 index 0000000000..e674fe59ed --- /dev/null +++ b/editor/src/editor/mvc/list_update.rs @@ -0,0 +1,88 @@ + +use crate::editor::ed_error::EdResult; +use crate::editor::markup::attribute::Attributes; +use crate::editor::markup::nodes; +use crate::editor::markup::nodes::MarkupNode; +use crate::editor::mvc::app_update::InputOutcome; +use crate::editor::mvc::ed_model::EdModel; +use crate::editor::mvc::ed_update::get_node_context; +use crate::editor::mvc::ed_update::NodeContext; +use crate::editor::syntax_highlight::HighlightStyle; +use crate::lang::ast::Expr2; +use crate::lang::pool::{PoolVec}; + +pub fn start_new_list(ed_model: &mut EdModel) -> EdResult { + let NodeContext { + old_caret_pos, + curr_mark_node_id, + curr_mark_node, + parent_id_opt, + ast_node_id, + } = get_node_context(&ed_model)?; + + let is_blank_node = curr_mark_node.is_blank(); + + let expr2_node = + Expr2::List{ + elem_var: ed_model.module.env.var_store.fresh(), + elems: PoolVec::empty(ed_model.module.env.pool) + }; + + let mark_node_pool = &mut ed_model.markup_node_pool; + + ed_model.module.env.pool.set(ast_node_id, expr2_node); + + let left_bracket_node = MarkupNode::Text { + content: nodes::LEFT_SQUARE_BR.to_owned(), + ast_node_id, + syn_high_style: HighlightStyle::Bracket, + attributes: Attributes::new(), + parent_id_opt: Some(curr_mark_node_id), // current node will be replaced with nested one + }; + + let left_bracket_node_id = mark_node_pool.add(left_bracket_node); + + let right_bracket_node = MarkupNode::Text { + content: nodes::RIGHT_SQUARE_BR.to_owned(), + ast_node_id, + syn_high_style: HighlightStyle::Bracket, + attributes: Attributes::new(), + parent_id_opt: Some(curr_mark_node_id), // current node will be replaced with nested one + }; + + let right_bracket_node_id = mark_node_pool.add(right_bracket_node); + + let nested_node = MarkupNode::Nested { + ast_node_id, + children_ids: vec![left_bracket_node_id, right_bracket_node_id], + parent_id_opt, + }; + + if is_blank_node { + mark_node_pool.replace_node(curr_mark_node_id, nested_node); + + // remove data corresponding to Blank node + ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?; + + ed_model.simple_move_carets_right(nodes::LEFT_SQUARE_BR.len()); + + // update GridNodeMap and CodeLines + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column, + nodes::LEFT_SQUARE_BR, + left_bracket_node_id, + )?; + + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column + nodes::LEFT_SQUARE_BR.len(), + nodes::RIGHT_SQUARE_BR, + right_bracket_node_id, + )?; + + Ok(InputOutcome::Accepted) + } else { + Ok(InputOutcome::Ignored) + } +} \ No newline at end of file diff --git a/editor/src/editor/mvc/mod.rs b/editor/src/editor/mvc/mod.rs index b393cfd0a2..64ee02304f 100644 --- a/editor/src/editor/mvc/mod.rs +++ b/editor/src/editor/mvc/mod.rs @@ -6,4 +6,5 @@ pub mod ed_view; mod int_update; mod lookup_update; mod record_update; +mod list_update; mod string_update; diff --git a/editor/src/lang/ast.rs b/editor/src/lang/ast.rs index b1b75b0554..d61669e39a 100644 --- a/editor/src/lang/ast.rs +++ b/editor/src/lang/ast.rs @@ -347,8 +347,9 @@ impl RecordField { pub fn expr2_to_string(node_id: NodeId, pool: &Pool) -> String { let mut full_string = String::new(); + let expr2 = pool.get(node_id); - expr2_to_string_helper(node_id, 0, pool, &mut full_string); + expr2_to_string_helper(expr2, 0, pool, &mut full_string); full_string } @@ -361,13 +362,11 @@ fn get_spacing(indent_level: usize) -> String { } fn expr2_to_string_helper( - node_id: NodeId, + expr2: &Expr2, indent_level: usize, pool: &Pool, out_string: &mut String, ) { - let expr2 = pool.get(node_id); - out_string.push_str(&get_spacing(indent_level)); match expr2 { @@ -384,11 +383,7 @@ fn expr2_to_string_helper( Expr2::EmptyRecord => out_string.push_str("EmptyRecord"), Expr2::Record { record_var, fields } => { out_string.push_str("Record:\n"); - out_string.push_str(&format!( - "{}Var({:?})\n", - get_spacing(indent_level + 1), - record_var - )); + out_string.push_str(&var_to_string(&record_var, indent_level + 1)); out_string.push_str(&format!("{}fields: [\n", get_spacing(indent_level + 1))); @@ -427,7 +422,8 @@ fn expr2_to_string_helper( var, )); - expr2_to_string_helper(*val_node_id, indent_level + 3, pool, out_string); + let val_expr2 = pool.get(*val_node_id); + expr2_to_string_helper(val_expr2, indent_level + 3, pool, out_string); out_string.push_str(&format!("{})\n", get_spacing(indent_level + 2))); } } @@ -435,6 +431,25 @@ fn expr2_to_string_helper( out_string.push_str(&format!("{}]\n", get_spacing(indent_level + 1))); } + Expr2::List { elem_var, elems} => { + out_string.push_str("List:\n"); + out_string.push_str(&var_to_string(elem_var, indent_level + 1)); + out_string.push_str(&format!("{}elems: [\n", get_spacing(indent_level + 1))); + + let mut first_elt = true; + + for elem_expr2 in elems.iter(pool) { + if !first_elt { + out_string.push_str(", ") + } else { + first_elt = false; + } + + expr2_to_string_helper(elem_expr2, indent_level + 1, pool, out_string) + } + + out_string.push_str(&format!("{}]\n", get_spacing(indent_level + 1))); + } Expr2::InvalidLookup(pool_str) => { out_string.push_str(&format!("InvalidLookup({})", pool_str.as_str(pool))); } @@ -447,6 +462,14 @@ fn expr2_to_string_helper( out_string.push('\n'); } +fn var_to_string( some_var: &Variable, indent_level: usize) -> String { + format!( + "{}Var({:?})\n", + get_spacing(indent_level + 1), + some_var + ) +} + #[test] fn size_of_expr() { assert_eq!(std::mem::size_of::(), crate::lang::pool::NODE_BYTES); diff --git a/editor/tests/solve_expr2.rs b/editor/tests/solve_expr2.rs index 374afd6590..91a2964fc9 100644 --- a/editor/tests/solve_expr2.rs +++ b/editor/tests/solve_expr2.rs @@ -62,7 +62,6 @@ fn infer_eq(actual: &str, expected_str: &str) { let mut var_store = VarStore::default(); let var = var_store.fresh(); let dep_idents = IdentIds::exposed_builtins(8); - let exposed_ident_ids = IdentIds::default(); let mut module_ids = ModuleIds::default(); let mod_id = module_ids.get_or_insert(&"ModId123".into()); @@ -121,6 +120,7 @@ fn infer_eq(actual: &str, expected_str: &str) { module_ids, all_ident_ids: dep_idents, }; + let actual_str = content_to_string(content, &subs, mod_id, &interns); assert_eq!(actual_str, expected_str); @@ -208,7 +208,7 @@ fn constrain_empty_list() { infer_eq( indoc!( r#" - [] + [ ] "# ), "List *",