diff --git a/ast/src/constrain.rs b/ast/src/constrain.rs index 1454f1d936..7a8772baca 100644 --- a/ast/src/constrain.rs +++ b/ast/src/constrain.rs @@ -945,7 +945,7 @@ pub fn constrain_expr<'a>( Expr2::Closure { args, name, - body: body_id, + body_id, function_type: fn_var, extra, .. diff --git a/ast/src/lang/core/def/def.rs b/ast/src/lang/core/def/def.rs index c8654b3d73..5cc144f450 100644 --- a/ast/src/lang/core/def/def.rs +++ b/ast/src/lang/core/def/def.rs @@ -488,7 +488,7 @@ fn canonicalize_pending_def<'a>( match loc_can_expr { Expr2::Closure { args: closure_args, - body, + body_id, extra, name: closure_symbol, .. @@ -570,7 +570,7 @@ fn canonicalize_pending_def<'a>( arguments, rigids: env.pool.add(rigids), return_type, - body, + body_id, }; let def = Def::Function(function_def); @@ -655,7 +655,7 @@ fn canonicalize_pending_def<'a>( match loc_can_expr { Expr2::Closure { args: closure_args, - body, + body_id, extra, name: closure_symbol, .. @@ -702,7 +702,7 @@ fn canonicalize_pending_def<'a>( name: symbol, arguments, return_var: env.var_store.fresh(), - body, + body_id, }; let def = Def::Function(function_def); diff --git a/ast/src/lang/core/expr/expr2.rs b/ast/src/lang/core/expr/expr2.rs index e06d169ece..9c535c4830 100644 --- a/ast/src/lang/core/expr/expr2.rs +++ b/ast/src/lang/core/expr/expr2.rs @@ -109,7 +109,7 @@ pub enum Expr2 { Closure { args: PoolVec<(Variable, NodeId)>, // 8B name: Symbol, // 8B - body: ExprId, // 4B + body_id: ExprId, // 4B function_type: Variable, // 4B recursive: Recursive, // 1B extra: NodeId, // 4B diff --git a/ast/src/lang/core/expr/expr_to_expr2.rs b/ast/src/lang/core/expr/expr_to_expr2.rs index febad6b13a..a68e69da11 100644 --- a/ast/src/lang/core/expr/expr_to_expr2.rs +++ b/ast/src/lang/core/expr/expr_to_expr2.rs @@ -488,7 +488,7 @@ pub fn to_expr2<'a>( name: symbol, recursive: Recursive::NotRecursive, args: can_args, - body: env.add(body_expr, loc_body_expr.region), + body_id: env.add(body_expr, loc_body_expr.region), extra: env.pool.add(extra), }, output, diff --git a/ast/src/lang/core/fun_def.rs b/ast/src/lang/core/fun_def.rs index 588d07d996..14c1d6ff88 100644 --- a/ast/src/lang/core/fun_def.rs +++ b/ast/src/lang/core/fun_def.rs @@ -18,13 +18,13 @@ pub enum FunctionDef { arguments: PoolVec<(PatternId, Type2)>, // 8B rigids: NodeId, // 4B return_type: TypeId, // 4B - body: ExprId, // 4B + body_id: ExprId, // 4B }, NoAnnotation { name: Symbol, // 8B arguments: PoolVec<(PatternId, Variable)>, // 8B return_var: Variable, // 4B - body: ExprId, // 4B + body_id: ExprId, // 4B }, } @@ -36,25 +36,25 @@ impl ShallowClone for FunctionDef { arguments, rigids, return_type, - body, + body_id, } => Self::WithAnnotation { name: *name, arguments: arguments.shallow_clone(), rigids: *rigids, return_type: *return_type, - body: *body, + body_id: *body_id, }, Self::NoAnnotation { name, arguments, return_var, - body, + body_id, } => Self::NoAnnotation { name: *name, arguments: arguments.shallow_clone(), return_var: *return_var, - body: *body, + body_id: *body_id, }, } } diff --git a/cli/benches/time_bench.rs b/cli/benches/time_bench.rs index f4c8f6e8be..0a99bfd154 100644 --- a/cli/benches/time_bench.rs +++ b/cli/benches/time_bench.rs @@ -1,7 +1,7 @@ use std::time::Duration; use cli_utils::bench_utils::{ - bench_cfold, bench_deriv, bench_nqueens, bench_quicksort, bench_rbtree_ck, bench_rbtree_delete, + bench_cfold, bench_deriv, bench_nqueens, bench_quicksort, bench_rbtree_ck, }; use criterion::{measurement::WallTime, BenchmarkGroup, Criterion, SamplingMode}; diff --git a/code_markup/src/markup/convert/from_ast.rs b/code_markup/src/markup/convert/from_ast.rs new file mode 100644 index 0000000000..e84a3ac58f --- /dev/null +++ b/code_markup/src/markup/convert/from_ast.rs @@ -0,0 +1,28 @@ +use bumpalo::Bump; +use roc_ast::{ast_error::ASTResult, lang::{core::ast::AST, env::Env}}; +use roc_module::symbol::Interns; + +use crate::{markup::{convert::{from_def2::def2_to_markup, from_header::header_to_markup}, nodes::set_parent_for_all}, slow_pool::{MarkNodeId, SlowPool}}; + + +pub fn ast_to_mark_nodes<'a, 'b>( + arena: &'a Bump, + env: &mut Env<'b>, + ast: &AST, + mark_node_pool: &mut SlowPool, + interns: &Interns, +) -> ASTResult> { + let mut all_mark_node_ids = vec![header_to_markup(&ast.header, mark_node_pool)]; + + for &def_id in ast.def_ids.iter() { + let def2 = env.pool.get(def_id); + + let expr2_markup_id = def2_to_markup(arena, env, def2, def_id, mark_node_pool, interns)?; + + set_parent_for_all(expr2_markup_id, mark_node_pool); + + all_mark_node_ids.push(expr2_markup_id); + } + + Ok(all_mark_node_ids) +} \ No newline at end of file diff --git a/code_markup/src/markup/convert/from_def2.rs b/code_markup/src/markup/convert/from_def2.rs new file mode 100644 index 0000000000..cdc220503c --- /dev/null +++ b/code_markup/src/markup/convert/from_def2.rs @@ -0,0 +1,57 @@ +use crate::{markup::{common_nodes::new_blank_mn_w_nls, top_level_def::tld_mark_node}, slow_pool::{MarkNodeId, SlowPool}}; + +use super::{from_expr2::expr2_to_markup}; + +use bumpalo::Bump; +use roc_ast::{ + ast_error::ASTResult, + lang::{ + core::{ + ast::{ASTNodeId}, + def::def2::{Def2, DefId}, + }, + env::Env, + }, +}; +use roc_module::symbol::Interns; + +pub fn def2_to_markup<'a, 'b>( + arena: &'a Bump, + env: &mut Env<'b>, + def2: &Def2, + def2_node_id: DefId, + mark_node_pool: &mut SlowPool, + interns: &Interns, +) -> ASTResult { + let ast_node_id = ASTNodeId::ADefId(def2_node_id); + + let mark_node_id = match def2 { + Def2::ValueDef { + identifier_id, + expr_id, + } => { + let expr_mn_id = expr2_to_markup( + arena, + env, + env.pool.get(*expr_id), + *expr_id, + mark_node_pool, + interns, + )?; + + let tld_mn = tld_mark_node( + *identifier_id, + expr_mn_id, + ast_node_id, + mark_node_pool, + env, + interns, + )?; + + mark_node_pool.add(tld_mn) + } + Def2::Blank => mark_node_pool.add(new_blank_mn_w_nls(ast_node_id, None, 2)), + }; + + Ok(mark_node_id) +} \ No newline at end of file diff --git a/code_markup/src/markup/convert/from_expr2.rs b/code_markup/src/markup/convert/from_expr2.rs new file mode 100644 index 0000000000..559b4cea57 --- /dev/null +++ b/code_markup/src/markup/convert/from_expr2.rs @@ -0,0 +1,278 @@ + +use crate::{markup::{attribute::Attributes, common_nodes::{ + new_blank_mn, new_colon_mn, new_comma_mn, new_equals_mn, new_left_accolade_mn, + new_left_square_mn, new_right_accolade_mn, new_right_square_mn, + }, nodes::{MarkupNode, get_string, new_markup_node}}, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle}; + +use bumpalo::Bump; +use roc_ast::{ast_error::ASTResult, lang::{core::{ast::ASTNodeId, expr::{ + expr2::{Expr2, ExprId}, + record_field::RecordField, + }, pattern::{Pattern2, get_identifier_string}, val_def::ValueDef}, env::Env}}; +use roc_module::symbol::Interns; + +// make Markup Nodes: generate String representation, assign Highlighting Style +pub fn expr2_to_markup<'a, 'b>( + arena: &'a Bump, + env: &mut Env<'b>, + expr2: &Expr2, + expr2_node_id: ExprId, + mark_node_pool: &mut SlowPool, + interns: &Interns, +) -> ASTResult { + let ast_node_id = ASTNodeId::AExprId(expr2_node_id); + + let mark_node_id = match expr2 { + Expr2::SmallInt { text, .. } + | Expr2::I128 { text, .. } + | Expr2::U128 { text, .. } + | Expr2::Float { text, .. } => { + let num_str = get_string(env, text); + + new_markup_node(num_str, ast_node_id, HighlightStyle::Number, mark_node_pool) + } + Expr2::Str(text) => new_markup_node( + "\"".to_owned() + text.as_str(env.pool) + "\"", + ast_node_id, + HighlightStyle::String, + mark_node_pool, + ), + Expr2::GlobalTag { name, .. } => new_markup_node( + get_string(env, name), + ast_node_id, + HighlightStyle::Type, + mark_node_pool, + ), + Expr2::Call { expr: expr_id, .. } => { + let expr = env.pool.get(*expr_id); + expr2_to_markup(arena, env, expr, *expr_id, mark_node_pool, interns)? + } + Expr2::Var(symbol) => { + //TODO make bump_format with arena + let text = format!("{:?}", symbol); + new_markup_node(text, ast_node_id, HighlightStyle::Variable, mark_node_pool) + } + Expr2::List { elems, .. } => { + let mut children_ids = + vec![mark_node_pool.add(new_left_square_mn(expr2_node_id, None))]; + + let indexed_node_ids: Vec<(usize, ExprId)> = + elems.iter(env.pool).copied().enumerate().collect(); + + for (idx, node_id) in indexed_node_ids.iter() { + let sub_expr2 = env.pool.get(*node_id); + + children_ids.push(expr2_to_markup( + arena, + env, + sub_expr2, + *node_id, + mark_node_pool, + interns, + )?); + + if idx + 1 < elems.len() { + children_ids.push(mark_node_pool.add(new_comma_mn(expr2_node_id, None))); + } + } + children_ids.push(mark_node_pool.add(new_right_square_mn(expr2_node_id, None))); + + let list_node = MarkupNode::Nested { + ast_node_id, + children_ids, + parent_id_opt: None, + newlines_at_end: 0, + }; + + mark_node_pool.add(list_node) + } + Expr2::EmptyRecord => { + let children_ids = vec![ + mark_node_pool.add(new_left_accolade_mn(expr2_node_id, None)), + mark_node_pool.add(new_right_accolade_mn(expr2_node_id, None)), + ]; + + let record_node = MarkupNode::Nested { + ast_node_id, + children_ids, + parent_id_opt: None, + newlines_at_end: 0, + }; + + mark_node_pool.add(record_node) + } + Expr2::Record { fields, .. } => { + let mut children_ids = + vec![mark_node_pool.add(new_left_accolade_mn(expr2_node_id, None))]; + + for (idx, field_node_id) in fields.iter_node_ids().enumerate() { + let record_field = env.pool.get(field_node_id); + + let field_name = record_field.get_record_field_pool_str(); + + children_ids.push(new_markup_node( + field_name.as_str(env.pool).to_owned(), + ast_node_id, + HighlightStyle::RecordField, + mark_node_pool, + )); + + match record_field { + RecordField::InvalidLabelOnly(_, _) => (), + RecordField::LabelOnly(_, _, _) => (), + RecordField::LabeledValue(_, _, sub_expr2_node_id) => { + children_ids.push(mark_node_pool.add(new_colon_mn(expr2_node_id, None))); + + let sub_expr2 = env.pool.get(*sub_expr2_node_id); + children_ids.push(expr2_to_markup( + arena, + env, + sub_expr2, + *sub_expr2_node_id, + mark_node_pool, + interns, + )?); + } + } + + if idx + 1 < fields.len() { + children_ids.push(mark_node_pool.add(new_comma_mn(expr2_node_id, None))); + } + } + + children_ids.push(mark_node_pool.add(new_right_accolade_mn(expr2_node_id, None))); + + let record_node = MarkupNode::Nested { + ast_node_id, + children_ids, + parent_id_opt: None, + newlines_at_end: 0, + }; + + mark_node_pool.add(record_node) + } + Expr2::Blank => mark_node_pool.add(new_blank_mn(ast_node_id, None)), + Expr2::LetValue { + def_id, + body_id: _, + body_var: _, + } => { + let pattern_id = env.pool.get(*def_id).get_pattern_id(); + + let pattern2 = env.pool.get(pattern_id); + + let val_name = get_identifier_string(pattern2, interns)?; + + let val_name_mn = MarkupNode::Text { + content: val_name, + ast_node_id, + syn_high_style: HighlightStyle::Variable, + attributes: Attributes::default(), + parent_id_opt: None, + newlines_at_end: 0, + }; + + let val_name_mn_id = mark_node_pool.add(val_name_mn); + + let equals_mn_id = mark_node_pool.add(new_equals_mn(ast_node_id, None)); + + let value_def = env.pool.get(*def_id); + + match value_def { + ValueDef::NoAnnotation { + pattern_id: _, + expr_id, + expr_var: _, + } => { + let body_mn_id = expr2_to_markup( + arena, + env, + env.pool.get(*expr_id), + *expr_id, + mark_node_pool, + interns, + )?; + + let body_mn = mark_node_pool.get_mut(body_mn_id); + body_mn.add_newline_at_end(); + + let full_let_node = MarkupNode::Nested { + ast_node_id, + children_ids: vec![val_name_mn_id, equals_mn_id, body_mn_id], + parent_id_opt: None, + newlines_at_end: 1, + }; + + mark_node_pool.add(full_let_node) + } + other => { + unimplemented!( + "I don't know how to convert {:?} into a MarkupNode yet.", + other + ) + } + } + } + Expr2::Closure{ + function_type, + name, + recursive:_, + args, + body_id, + extra:_ + } => { + let func_name = name.ident_str(interns).as_str(); + + let arg_names: Vec<&str> = + args.iter(env.pool).map( + | (_, arg_node_id) | { + let arg_pattern2 = env.pool.get(*arg_node_id); + + match arg_pattern2 { + Pattern2::Identifier(id_symbol) => { + id_symbol.ident_str(interns).as_str() + }, + other => { + todo!("TODO: support the following pattern2 as function arg: {:?}", other); + } + } + } + ) + .collect(); + + for (_, arg_node_id) in args.iter(env.pool) { + let arg_pattern2 = env.pool.get(*arg_node_id); + + match arg_pattern2 { + Pattern2::Identifier(id_symbol) => { + dbg!(id_symbol.ident_str(interns).as_str()); + }, + other => { + todo!("TODO: support the following pattern2 as function arg: {:?}", other); + } + } + } + + let body_expr = env.pool.get(*body_id); + let body_mark_node = expr2_to_markup( + arena, + env, + body_expr, + *body_id, + mark_node_pool, + interns, + )?; + + panic!("TODO") + } + Expr2::RuntimeError() => new_markup_node( + "RunTimeError".to_string(), + ast_node_id, + HighlightStyle::Blank, + mark_node_pool, + ), + rest => todo!("implement expr2_to_markup for {:?}", rest), + }; + + Ok(mark_node_id) +} \ No newline at end of file diff --git a/code_markup/src/markup/convert/from_header.rs b/code_markup/src/markup/convert/from_header.rs new file mode 100644 index 0000000000..376fafccb1 --- /dev/null +++ b/code_markup/src/markup/convert/from_header.rs @@ -0,0 +1,195 @@ +use roc_ast::lang::core::{ast::ASTNodeId, expr::expr2::ExprId, header::AppHeader}; + +use crate::{markup::{attribute::Attributes, common_nodes::{new_comma_mn, new_left_accolade_mn, new_left_square_mn, new_right_accolade_mn, new_right_square_mn}, nodes::{MarkupNode, set_parent_for_all}}, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle}; + + +pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -> MarkNodeId { + let expr_id = app_header.ast_node_id; + let ast_node_id = ASTNodeId::AExprId(expr_id); + + let app_node_id = header_mn("app ".to_owned(), expr_id, mark_node_pool); + + let app_name_node_id = header_val_mn( + app_header.app_name.clone(), + expr_id, + HighlightStyle::String, + mark_node_pool, + ); + + let full_app_node = MarkupNode::Nested { + ast_node_id, + children_ids: vec![app_node_id, app_name_node_id], + parent_id_opt: None, + newlines_at_end: 1, + }; + + let packages_node_id = header_mn(" packages ".to_owned(), expr_id, mark_node_pool); + + let pack_left_acc_node_id = mark_node_pool.add(new_left_accolade_mn(expr_id, None)); + + let pack_base_node_id = header_val_mn( + "base: ".to_owned(), + expr_id, + HighlightStyle::RecordField, + mark_node_pool, + ); + + let pack_val_node_id = header_val_mn( + app_header.packages_base.clone(), + expr_id, + HighlightStyle::String, + mark_node_pool, + ); + + let pack_right_acc_node_id = mark_node_pool.add(new_right_accolade_mn(expr_id, None)); + + let full_packages_node = MarkupNode::Nested { + ast_node_id, + children_ids: vec![ + packages_node_id, + pack_left_acc_node_id, + pack_base_node_id, + pack_val_node_id, + pack_right_acc_node_id, + ], + parent_id_opt: None, + newlines_at_end: 1, + }; + + let imports_node_id = header_mn(" imports ".to_owned(), expr_id, mark_node_pool); + + let imports_left_square_node_id = mark_node_pool.add(new_left_square_mn(expr_id, None)); + + let mut import_child_ids: Vec = add_header_mn_list( + &app_header.imports, + expr_id, + HighlightStyle::Import, + mark_node_pool, + ); + + let imports_right_square_node_id = mark_node_pool.add(new_right_square_mn(expr_id, None)); + + let mut full_import_children = vec![imports_node_id, imports_left_square_node_id]; + + full_import_children.append(&mut import_child_ids); + full_import_children.push(imports_right_square_node_id); + + let full_import_node = MarkupNode::Nested { + ast_node_id, + children_ids: full_import_children, + parent_id_opt: None, + newlines_at_end: 1, + }; + + let provides_node_id = header_mn(" provides ".to_owned(), expr_id, mark_node_pool); + + let provides_left_square_node_id = mark_node_pool.add(new_left_square_mn(expr_id, None)); + + let mut provides_val_node_ids: Vec = add_header_mn_list( + &app_header.provides, + expr_id, + HighlightStyle::Provides, + mark_node_pool, + ); + + let provides_right_square_node_id = mark_node_pool.add(new_right_square_mn(expr_id, None)); + + let provides_end_node_id = header_mn(" to base".to_owned(), expr_id, mark_node_pool); + + let mut full_provides_children = vec![provides_node_id, provides_left_square_node_id]; + + full_provides_children.append(&mut provides_val_node_ids); + full_provides_children.push(provides_right_square_node_id); + full_provides_children.push(provides_end_node_id); + + let full_provides_node = MarkupNode::Nested { + ast_node_id, + children_ids: full_provides_children, + parent_id_opt: None, + newlines_at_end: 1, + }; + + let full_app_node_id = mark_node_pool.add(full_app_node); + let full_packages_node = mark_node_pool.add(full_packages_node); + let full_import_node_id = mark_node_pool.add(full_import_node); + let full_provides_node_id = mark_node_pool.add(full_provides_node); + + let header_mark_node = MarkupNode::Nested { + ast_node_id, + children_ids: vec![ + full_app_node_id, + full_packages_node, + full_import_node_id, + full_provides_node_id, + ], + parent_id_opt: None, + newlines_at_end: 1, + }; + + let header_mn_id = mark_node_pool.add(header_mark_node); + + set_parent_for_all(header_mn_id, mark_node_pool); + + header_mn_id +} + +// Used for provides and imports +fn add_header_mn_list( + str_vec: &[String], + expr_id: ExprId, + highlight_style: HighlightStyle, + mark_node_pool: &mut SlowPool, +) -> Vec { + let nr_of_elts = str_vec.len(); + + str_vec + .iter() + .enumerate() + .map(|(indx, provide_str)| { + let provide_str = header_val_mn( + provide_str.to_owned(), + expr_id, + highlight_style, + mark_node_pool, + ); + + if indx != nr_of_elts - 1 { + vec![provide_str, mark_node_pool.add(new_comma_mn(expr_id, None))] + } else { + vec![provide_str] + } + }) + .flatten() + .collect() +} + +fn header_mn(content: String, expr_id: ExprId, mark_node_pool: &mut SlowPool) -> MarkNodeId { + let mark_node = MarkupNode::Text { + content, + ast_node_id: ASTNodeId::AExprId(expr_id), + syn_high_style: HighlightStyle::PackageRelated, + attributes: Attributes::default(), + parent_id_opt: None, + newlines_at_end: 0, + }; + + mark_node_pool.add(mark_node) +} + +fn header_val_mn( + content: String, + expr_id: ExprId, + highlight_style: HighlightStyle, + mark_node_pool: &mut SlowPool, +) -> MarkNodeId { + let mark_node = MarkupNode::Text { + content, + ast_node_id: ASTNodeId::AExprId(expr_id), + syn_high_style: highlight_style, + attributes: Attributes::default(), + parent_id_opt: None, + newlines_at_end: 0, + }; + + mark_node_pool.add(mark_node) +} \ No newline at end of file diff --git a/code_markup/src/markup/convert/mod.rs b/code_markup/src/markup/convert/mod.rs new file mode 100644 index 0000000000..4e6d5618c7 --- /dev/null +++ b/code_markup/src/markup/convert/mod.rs @@ -0,0 +1,4 @@ +pub mod from_ast; +pub mod from_def2; +pub mod from_expr2; +pub mod from_header; \ No newline at end of file diff --git a/code_markup/src/markup/mod.rs b/code_markup/src/markup/mod.rs index e3ce137f80..05480f0f2c 100644 --- a/code_markup/src/markup/mod.rs +++ b/code_markup/src/markup/mod.rs @@ -1,4 +1,5 @@ pub mod attribute; pub mod common_nodes; pub mod nodes; +pub mod convert; pub mod top_level_def; diff --git a/code_markup/src/markup/nodes.rs b/code_markup/src/markup/nodes.rs index cea08f288b..1ccffaa6db 100644 --- a/code_markup/src/markup/nodes.rs +++ b/code_markup/src/markup/nodes.rs @@ -1,38 +1,15 @@ use crate::{ - markup::common_nodes::{ - new_blank_mn, new_colon_mn, new_comma_mn, new_equals_mn, new_left_accolade_mn, - new_left_square_mn, new_right_accolade_mn, new_right_square_mn, - }, markup_error::MarkResult, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle, }; use super::{ - attribute::Attributes, common_nodes::new_blank_mn_w_nls, top_level_def::tld_mark_node, + attribute::Attributes }; use crate::markup_error::{ExpectedTextNode, NestedNodeMissingChild, NestedNodeRequired}; -use bumpalo::Bump; -use roc_ast::{ - ast_error::ASTResult, - lang::{ - core::{ - ast::{ASTNodeId, AST}, - def::def2::{Def2, DefId}, - expr::{ - expr2::{Expr2, ExprId}, - record_field::RecordField, - }, - header::AppHeader, - pattern::get_identifier_string, - val_def::ValueDef, - }, - env::Env, - }, - mem_pool::pool_str::PoolStr, -}; -use roc_module::symbol::Interns; +use roc_ast::{lang::{core::ast::ASTNodeId, env::Env}, mem_pool::pool_str::PoolStr}; use roc_utils::{index_of, slice_get}; use std::fmt; @@ -273,7 +250,7 @@ impl MarkupNode { } } -fn get_string<'a>(env: &Env<'a>, pool_str: &PoolStr) -> String { +pub fn get_string<'a>(env: &Env<'a>, pool_str: &PoolStr) -> String { pool_str.as_str(env.pool).to_owned() } @@ -287,7 +264,7 @@ pub const COMMA: &str = ", "; pub const STRING_QUOTES: &str = "\"\""; pub const EQUALS: &str = " = "; -fn new_markup_node( +pub fn new_markup_node( text: String, node_id: ASTNodeId, highlight_style: HighlightStyle, @@ -305,261 +282,6 @@ fn new_markup_node( mark_node_pool.add(node) } -pub fn def2_to_markup<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, - def2: &Def2, - def2_node_id: DefId, - mark_node_pool: &mut SlowPool, - interns: &Interns, -) -> ASTResult { - let ast_node_id = ASTNodeId::ADefId(def2_node_id); - - let mark_node_id = match def2 { - Def2::ValueDef { - identifier_id, - expr_id, - } => { - let expr_mn_id = expr2_to_markup( - arena, - env, - env.pool.get(*expr_id), - *expr_id, - mark_node_pool, - interns, - )?; - - let tld_mn = tld_mark_node( - *identifier_id, - expr_mn_id, - ast_node_id, - mark_node_pool, - env, - interns, - )?; - - mark_node_pool.add(tld_mn) - } - Def2::Blank => mark_node_pool.add(new_blank_mn_w_nls(ast_node_id, None, 2)), - }; - - Ok(mark_node_id) -} - -// make Markup Nodes: generate String representation, assign Highlighting Style -pub fn expr2_to_markup<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, - expr2: &Expr2, - expr2_node_id: ExprId, - mark_node_pool: &mut SlowPool, - interns: &Interns, -) -> ASTResult { - let ast_node_id = ASTNodeId::AExprId(expr2_node_id); - - let mark_node_id = match expr2 { - Expr2::SmallInt { text, .. } - | Expr2::I128 { text, .. } - | Expr2::U128 { text, .. } - | Expr2::Float { text, .. } => { - let num_str = get_string(env, text); - - new_markup_node(num_str, ast_node_id, HighlightStyle::Number, mark_node_pool) - } - Expr2::Str(text) => new_markup_node( - "\"".to_owned() + text.as_str(env.pool) + "\"", - ast_node_id, - HighlightStyle::String, - mark_node_pool, - ), - Expr2::GlobalTag { name, .. } => new_markup_node( - get_string(env, name), - ast_node_id, - HighlightStyle::Type, - mark_node_pool, - ), - Expr2::Call { expr: expr_id, .. } => { - let expr = env.pool.get(*expr_id); - expr2_to_markup(arena, env, expr, *expr_id, mark_node_pool, interns)? - } - Expr2::Var(symbol) => { - //TODO make bump_format with arena - let text = format!("{:?}", symbol); - new_markup_node(text, ast_node_id, HighlightStyle::Variable, mark_node_pool) - } - Expr2::List { elems, .. } => { - let mut children_ids = - vec![mark_node_pool.add(new_left_square_mn(expr2_node_id, None))]; - - let indexed_node_ids: Vec<(usize, ExprId)> = - elems.iter(env.pool).copied().enumerate().collect(); - - for (idx, node_id) in indexed_node_ids.iter() { - let sub_expr2 = env.pool.get(*node_id); - - children_ids.push(expr2_to_markup( - arena, - env, - sub_expr2, - *node_id, - mark_node_pool, - interns, - )?); - - if idx + 1 < elems.len() { - children_ids.push(mark_node_pool.add(new_comma_mn(expr2_node_id, None))); - } - } - children_ids.push(mark_node_pool.add(new_right_square_mn(expr2_node_id, None))); - - let list_node = MarkupNode::Nested { - ast_node_id, - children_ids, - parent_id_opt: None, - newlines_at_end: 0, - }; - - mark_node_pool.add(list_node) - } - Expr2::EmptyRecord => { - let children_ids = vec![ - mark_node_pool.add(new_left_accolade_mn(expr2_node_id, None)), - mark_node_pool.add(new_right_accolade_mn(expr2_node_id, None)), - ]; - - let record_node = MarkupNode::Nested { - ast_node_id, - children_ids, - parent_id_opt: None, - newlines_at_end: 0, - }; - - mark_node_pool.add(record_node) - } - Expr2::Record { fields, .. } => { - let mut children_ids = - vec![mark_node_pool.add(new_left_accolade_mn(expr2_node_id, None))]; - - for (idx, field_node_id) in fields.iter_node_ids().enumerate() { - let record_field = env.pool.get(field_node_id); - - let field_name = record_field.get_record_field_pool_str(); - - children_ids.push(new_markup_node( - field_name.as_str(env.pool).to_owned(), - ast_node_id, - HighlightStyle::RecordField, - mark_node_pool, - )); - - match record_field { - RecordField::InvalidLabelOnly(_, _) => (), - RecordField::LabelOnly(_, _, _) => (), - RecordField::LabeledValue(_, _, sub_expr2_node_id) => { - children_ids.push(mark_node_pool.add(new_colon_mn(expr2_node_id, None))); - - let sub_expr2 = env.pool.get(*sub_expr2_node_id); - children_ids.push(expr2_to_markup( - arena, - env, - sub_expr2, - *sub_expr2_node_id, - mark_node_pool, - interns, - )?); - } - } - - if idx + 1 < fields.len() { - children_ids.push(mark_node_pool.add(new_comma_mn(expr2_node_id, None))); - } - } - - children_ids.push(mark_node_pool.add(new_right_accolade_mn(expr2_node_id, None))); - - let record_node = MarkupNode::Nested { - ast_node_id, - children_ids, - parent_id_opt: None, - newlines_at_end: 0, - }; - - mark_node_pool.add(record_node) - } - Expr2::Blank => mark_node_pool.add(new_blank_mn(ast_node_id, None)), - Expr2::LetValue { - def_id, - body_id: _, - body_var: _, - } => { - let pattern_id = env.pool.get(*def_id).get_pattern_id(); - - let pattern2 = env.pool.get(pattern_id); - - let val_name = get_identifier_string(pattern2, interns)?; - - let val_name_mn = MarkupNode::Text { - content: val_name, - ast_node_id, - syn_high_style: HighlightStyle::Variable, - attributes: Attributes::default(), - parent_id_opt: None, - newlines_at_end: 0, - }; - - let val_name_mn_id = mark_node_pool.add(val_name_mn); - - let equals_mn_id = mark_node_pool.add(new_equals_mn(ast_node_id, None)); - - let value_def = env.pool.get(*def_id); - - match value_def { - ValueDef::NoAnnotation { - pattern_id: _, - expr_id, - expr_var: _, - } => { - let body_mn_id = expr2_to_markup( - arena, - env, - env.pool.get(*expr_id), - *expr_id, - mark_node_pool, - interns, - )?; - - let body_mn = mark_node_pool.get_mut(body_mn_id); - body_mn.add_newline_at_end(); - - let full_let_node = MarkupNode::Nested { - ast_node_id, - children_ids: vec![val_name_mn_id, equals_mn_id, body_mn_id], - parent_id_opt: None, - newlines_at_end: 1, - }; - - mark_node_pool.add(full_let_node) - } - other => { - unimplemented!( - "I don't know how to convert {:?} into a MarkupNode yet.", - other - ) - } - } - } - Expr2::RuntimeError() => new_markup_node( - "RunTimeError".to_string(), - ast_node_id, - HighlightStyle::Blank, - mark_node_pool, - ), - rest => todo!("implement expr2_to_markup for {:?}", rest), - }; - - Ok(mark_node_id) -} - pub fn set_parent_for_all(markup_node_id: MarkNodeId, mark_node_pool: &mut SlowPool) { let node = mark_node_pool.get(markup_node_id); @@ -606,218 +328,6 @@ pub fn set_parent_for_all_helper( } } -fn header_mn(content: String, expr_id: ExprId, mark_node_pool: &mut SlowPool) -> MarkNodeId { - let mark_node = MarkupNode::Text { - content, - ast_node_id: ASTNodeId::AExprId(expr_id), - syn_high_style: HighlightStyle::PackageRelated, - attributes: Attributes::default(), - parent_id_opt: None, - newlines_at_end: 0, - }; - - mark_node_pool.add(mark_node) -} - -fn header_val_mn( - content: String, - expr_id: ExprId, - highlight_style: HighlightStyle, - mark_node_pool: &mut SlowPool, -) -> MarkNodeId { - let mark_node = MarkupNode::Text { - content, - ast_node_id: ASTNodeId::AExprId(expr_id), - syn_high_style: highlight_style, - attributes: Attributes::default(), - parent_id_opt: None, - newlines_at_end: 0, - }; - - mark_node_pool.add(mark_node) -} - -pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -> MarkNodeId { - let expr_id = app_header.ast_node_id; - let ast_node_id = ASTNodeId::AExprId(expr_id); - - let app_node_id = header_mn("app ".to_owned(), expr_id, mark_node_pool); - - let app_name_node_id = header_val_mn( - app_header.app_name.clone(), - expr_id, - HighlightStyle::String, - mark_node_pool, - ); - - let full_app_node = MarkupNode::Nested { - ast_node_id, - children_ids: vec![app_node_id, app_name_node_id], - parent_id_opt: None, - newlines_at_end: 1, - }; - - let packages_node_id = header_mn(" packages ".to_owned(), expr_id, mark_node_pool); - - let pack_left_acc_node_id = mark_node_pool.add(new_left_accolade_mn(expr_id, None)); - - let pack_base_node_id = header_val_mn( - "base: ".to_owned(), - expr_id, - HighlightStyle::RecordField, - mark_node_pool, - ); - - let pack_val_node_id = header_val_mn( - app_header.packages_base.clone(), - expr_id, - HighlightStyle::String, - mark_node_pool, - ); - - let pack_right_acc_node_id = mark_node_pool.add(new_right_accolade_mn(expr_id, None)); - - let full_packages_node = MarkupNode::Nested { - ast_node_id, - children_ids: vec![ - packages_node_id, - pack_left_acc_node_id, - pack_base_node_id, - pack_val_node_id, - pack_right_acc_node_id, - ], - parent_id_opt: None, - newlines_at_end: 1, - }; - - let imports_node_id = header_mn(" imports ".to_owned(), expr_id, mark_node_pool); - - let imports_left_square_node_id = mark_node_pool.add(new_left_square_mn(expr_id, None)); - - let mut import_child_ids: Vec = add_header_mn_list( - &app_header.imports, - expr_id, - HighlightStyle::Import, - mark_node_pool, - ); - - let imports_right_square_node_id = mark_node_pool.add(new_right_square_mn(expr_id, None)); - - let mut full_import_children = vec![imports_node_id, imports_left_square_node_id]; - - full_import_children.append(&mut import_child_ids); - full_import_children.push(imports_right_square_node_id); - - let full_import_node = MarkupNode::Nested { - ast_node_id, - children_ids: full_import_children, - parent_id_opt: None, - newlines_at_end: 1, - }; - - let provides_node_id = header_mn(" provides ".to_owned(), expr_id, mark_node_pool); - - let provides_left_square_node_id = mark_node_pool.add(new_left_square_mn(expr_id, None)); - - let mut provides_val_node_ids: Vec = add_header_mn_list( - &app_header.provides, - expr_id, - HighlightStyle::Provides, - mark_node_pool, - ); - - let provides_right_square_node_id = mark_node_pool.add(new_right_square_mn(expr_id, None)); - - let provides_end_node_id = header_mn(" to base".to_owned(), expr_id, mark_node_pool); - - let mut full_provides_children = vec![provides_node_id, provides_left_square_node_id]; - - full_provides_children.append(&mut provides_val_node_ids); - full_provides_children.push(provides_right_square_node_id); - full_provides_children.push(provides_end_node_id); - - let full_provides_node = MarkupNode::Nested { - ast_node_id, - children_ids: full_provides_children, - parent_id_opt: None, - newlines_at_end: 1, - }; - - let full_app_node_id = mark_node_pool.add(full_app_node); - let full_packages_node = mark_node_pool.add(full_packages_node); - let full_import_node_id = mark_node_pool.add(full_import_node); - let full_provides_node_id = mark_node_pool.add(full_provides_node); - - let header_mark_node = MarkupNode::Nested { - ast_node_id, - children_ids: vec![ - full_app_node_id, - full_packages_node, - full_import_node_id, - full_provides_node_id, - ], - parent_id_opt: None, - newlines_at_end: 1, - }; - - let header_mn_id = mark_node_pool.add(header_mark_node); - - set_parent_for_all(header_mn_id, mark_node_pool); - - header_mn_id -} - -// Used for provides and imports -fn add_header_mn_list( - str_vec: &[String], - expr_id: ExprId, - highlight_style: HighlightStyle, - mark_node_pool: &mut SlowPool, -) -> Vec { - let nr_of_elts = str_vec.len(); - - str_vec - .iter() - .enumerate() - .map(|(indx, provide_str)| { - let provide_str = header_val_mn( - provide_str.to_owned(), - expr_id, - highlight_style, - mark_node_pool, - ); - - if indx != nr_of_elts - 1 { - vec![provide_str, mark_node_pool.add(new_comma_mn(expr_id, None))] - } else { - vec![provide_str] - } - }) - .flatten() - .collect() -} - -pub fn ast_to_mark_nodes<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, - ast: &AST, - mark_node_pool: &mut SlowPool, - interns: &Interns, -) -> ASTResult> { - let mut all_mark_node_ids = vec![header_to_markup(&ast.header, mark_node_pool)]; - - for &def_id in ast.def_ids.iter() { - let def2 = env.pool.get(def_id); - - let expr2_markup_id = def2_to_markup(arena, env, def2, def_id, mark_node_pool, interns)?; - - set_parent_for_all(expr2_markup_id, mark_node_pool); - - all_mark_node_ids.push(expr2_markup_id); - } - - Ok(all_mark_node_ids) -} impl fmt::Display for MarkupNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/editor/src/editor/mvc/ed_model.rs b/editor/src/editor/mvc/ed_model.rs index d255bdbeb5..4d4fda0faa 100644 --- a/editor/src/editor/mvc/ed_model.rs +++ b/editor/src/editor/mvc/ed_model.rs @@ -15,7 +15,7 @@ use roc_ast::lang::core::ast::{ASTNodeId, AST}; use roc_ast::lang::env::Env; use roc_ast::mem_pool::pool_str::PoolStr; use roc_ast::parse::parse_ast; -use roc_code_markup::markup::nodes::ast_to_mark_nodes; +use roc_code_markup::markup::convert::from_ast::ast_to_mark_nodes; use roc_code_markup::slow_pool::{MarkNodeId, SlowPool}; use roc_load::file::LoadedModule; use std::path::Path;