diff --git a/Cargo.lock b/Cargo.lock index cc26d15406..4070eb340f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3228,8 +3228,10 @@ dependencies = [ "libc", "page_size", "pretty_assertions 0.6.1", + "roc_builtins", "roc_can", "roc_collections", + "roc_load", "roc_module", "roc_parse", "roc_problem", @@ -3414,14 +3416,19 @@ dependencies = [ "maplit", "pretty_assertions 0.5.1", "pulldown-cmark", + "roc_ast", "roc_builtins", "roc_can", + "roc_code_markup", "roc_collections", + "roc_fmt", "roc_load", "roc_module", "roc_parse", "roc_region", "roc_types", + "tempfile", + "uuid", ] [[package]] diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 39bf52a471..a379da9d8e 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" description = "AST as used by the editor and (soon) docs. In contrast to the compiler, these types do not keep track of a location in a file." [dependencies] +roc_builtins = { path = "../compiler/builtins"} roc_can = { path = "../compiler/can" } roc_collections = { path = "../compiler/collections" } roc_region = { path = "../compiler/region" } @@ -15,6 +16,7 @@ roc_parse = { path = "../compiler/parse" } roc_problem = { path = "../compiler/problem" } roc_types = { path = "../compiler/types" } roc_unify = { path = "../compiler/unify"} +roc_load = { path = "../compiler/load" } arraystring = "0.3.0" bumpalo = { version = "3.6.1", features = ["collections"] } libc = "0.2" diff --git a/ast/src/canonicalization/canonicalize.rs b/ast/src/canonicalization/canonicalize.rs index 211e22cf97..ff013615d2 100644 --- a/ast/src/canonicalization/canonicalize.rs +++ b/ast/src/canonicalization/canonicalize.rs @@ -9,7 +9,7 @@ use crate::{ def::def::References, expr::{ expr2::{Expr2, ExprId, WhenBranch}, - expr_to_expr2::to_expr2, + expr_to_expr2::expr_to_expr2, output::Output, record_field::RecordField, }, @@ -147,7 +147,8 @@ fn canonicalize_field<'a>( // Both a label and a value, e.g. `{ name: "blah" }` RequiredValue(label, _, loc_expr) => { let field_var = env.var_store.fresh(); - let (loc_can_expr, output) = to_expr2(env, scope, &loc_expr.value, loc_expr.region); + let (loc_can_expr, output) = + expr_to_expr2(env, scope, &loc_expr.value, loc_expr.region); Ok(CanonicalField::LabelAndValue { label: label.value, @@ -211,7 +212,7 @@ pub(crate) fn canonicalize_when_branch<'a>( } let (value, mut branch_output) = - to_expr2(env, &mut scope, &branch.value.value, branch.value.region); + expr_to_expr2(env, &mut scope, &branch.value.value, branch.value.region); let value_id = env.pool.add(value); env.set_region(value_id, branch.value.region); @@ -219,7 +220,7 @@ pub(crate) fn canonicalize_when_branch<'a>( None => None, Some(loc_expr) => { let (can_guard, guard_branch_output) = - to_expr2(env, &mut scope, &loc_expr.value, loc_expr.region); + expr_to_expr2(env, &mut scope, &loc_expr.value, loc_expr.region); let expr_id = env.pool.add(can_guard); env.set_region(expr_id, loc_expr.region); diff --git a/ast/src/lang/core/def/def.rs b/ast/src/lang/core/def/def.rs index c8654b3d73..1fd54b4828 100644 --- a/ast/src/lang/core/def/def.rs +++ b/ast/src/lang/core/def/def.rs @@ -27,7 +27,7 @@ use ven_graph::{strongly_connected_components, topological_sort_into_groups}; use crate::{ lang::{ core::{ - expr::{expr2::Expr2, expr_to_expr2::to_expr2, output::Output}, + expr::{expr2::Expr2, expr_to_expr2::expr_to_expr2, output::Output}, fun_def::FunctionDef, pattern::{self, symbols_from_pattern, to_pattern_id, Pattern2, PatternId}, types::{to_annotation2, Alias, Annotation2, Signature, Type2, TypeId}, @@ -472,7 +472,7 @@ fn canonicalize_pending_def<'a>( }; let (loc_can_expr, can_output) = - to_expr2(env, scope, &loc_expr.value, loc_expr.region); + expr_to_expr2(env, scope, &loc_expr.value, loc_expr.region); output.references.union_mut(can_output.references.clone()); @@ -639,7 +639,8 @@ fn canonicalize_pending_def<'a>( env.closure_name_symbol = Some(*defined_symbol); }; - let (loc_can_expr, can_output) = to_expr2(env, scope, &loc_expr.value, loc_expr.region); + let (loc_can_expr, can_output) = + expr_to_expr2(env, scope, &loc_expr.value, loc_expr.region); output.references.union_mut(can_output.references.clone()); diff --git a/ast/src/lang/core/def/def_to_def2.rs b/ast/src/lang/core/def/def_to_def2.rs index 05cf2747a6..ff659b4310 100644 --- a/ast/src/lang/core/def/def_to_def2.rs +++ b/ast/src/lang/core/def/def_to_def2.rs @@ -20,11 +20,11 @@ pub fn defs_to_defs2<'a>( ) -> Vec { parsed_defs .iter() - .map(|loc| to_def2_from_def(arena, env, scope, &loc.value, region)) + .map(|loc| def_to_def2(arena, env, scope, &loc.value, region)) .collect() } -pub fn to_def2_from_def<'a>( +pub fn def_to_def2<'a>( arena: &'a Bump, env: &mut Env<'a>, scope: &mut Scope, @@ -34,8 +34,8 @@ pub fn to_def2_from_def<'a>( use roc_parse::ast::Def::*; match parsed_def { - SpaceBefore(inner_def, _) => to_def2_from_def(arena, env, scope, inner_def, region), - SpaceAfter(inner_def, _) => to_def2_from_def(arena, env, scope, inner_def, region), + SpaceBefore(inner_def, _) => def_to_def2(arena, env, scope, inner_def, region), + SpaceAfter(inner_def, _) => def_to_def2(arena, env, scope, inner_def, region), Body(&loc_pattern, &loc_expr) => { // TODO loc_pattern use identifier let expr2 = loc_expr_to_expr2(arena, loc_expr, env, scope, region).0; diff --git a/ast/src/lang/core/expr/expr_to_expr2.rs b/ast/src/lang/core/expr/expr_to_expr2.rs index febad6b13a..ebe8ba2fc9 100644 --- a/ast/src/lang/core/expr/expr_to_expr2.rs +++ b/ast/src/lang/core/expr/expr_to_expr2.rs @@ -36,12 +36,12 @@ pub fn loc_expr_to_expr2<'a>( ) -> (Expr2, Output) { let desugared_loc_expr = desugar_expr(arena, arena.alloc(loc_expr)); - to_expr2(env, scope, arena.alloc(desugared_loc_expr.value), region) + expr_to_expr2(env, scope, arena.alloc(desugared_loc_expr.value), region) } const ZERO: Region = Region::zero(); -pub fn to_expr2<'a>( +pub fn expr_to_expr2<'a>( env: &mut Env<'a>, scope: &mut Scope, parse_expr: &'a roc_parse::ast::Expr<'a>, @@ -139,7 +139,7 @@ pub fn to_expr2<'a>( let elems: PoolVec = PoolVec::with_capacity(items.len() as u32, env.pool); for (node_id, item) in elems.iter_node_ids().zip(items.iter()) { - let (expr, sub_output) = to_expr2(env, scope, &item.value, item.region); + let (expr, sub_output) = expr_to_expr2(env, scope, &item.value, item.region); output_ref.union(sub_output); @@ -188,7 +188,7 @@ pub fn to_expr2<'a>( final_comments: _, } => { let (can_update, update_out) = - to_expr2(env, scope, &loc_update.value, loc_update.region); + expr_to_expr2(env, scope, &loc_update.value, loc_update.region); if let Expr2::Var(symbol) = &can_update { match canonicalize_fields(env, scope, fields) { @@ -309,10 +309,11 @@ pub fn to_expr2<'a>( let mut output = Output::default(); for (condition, then_branch) in branches.iter() { - let (cond, cond_output) = to_expr2(env, scope, &condition.value, condition.region); + let (cond, cond_output) = + expr_to_expr2(env, scope, &condition.value, condition.region); let (then_expr, then_output) = - to_expr2(env, scope, &then_branch.value, then_branch.region); + expr_to_expr2(env, scope, &then_branch.value, then_branch.region); output.references.union_mut(cond_output.references); output.references.union_mut(then_output.references); @@ -321,7 +322,7 @@ pub fn to_expr2<'a>( } let (else_expr, else_output) = - to_expr2(env, scope, &final_else.value, final_else.region); + expr_to_expr2(env, scope, &final_else.value, final_else.region); output.references.union_mut(else_output.references); @@ -338,7 +339,8 @@ pub fn to_expr2<'a>( When(loc_cond, branches) => { // Infer the condition expression's type. let cond_var = env.var_store.fresh(); - let (can_cond, mut output) = to_expr2(env, scope, &loc_cond.value, loc_cond.region); + let (can_cond, mut output) = + expr_to_expr2(env, scope, &loc_cond.value, loc_cond.region); // the condition can never be a tail-call output.tail_call = None; @@ -411,7 +413,7 @@ pub fn to_expr2<'a>( } let (body_expr, new_output) = - to_expr2(env, &mut scope, &loc_body_expr.value, loc_body_expr.region); + expr_to_expr2(env, &mut scope, &loc_body_expr.value, loc_body_expr.region); let mut captured_symbols: MutSet = new_output.references.lookups.iter().copied().collect(); @@ -501,7 +503,7 @@ pub fn to_expr2<'a>( let fn_region = loc_fn.region; // Canonicalize the function expression and its arguments - let (fn_expr, mut output) = to_expr2(env, scope, &loc_fn.value, fn_region); + let (fn_expr, mut output) = expr_to_expr2(env, scope, &loc_fn.value, fn_region); // The function's return type let args = PoolVec::with_capacity(loc_args.len() as u32, env.pool); @@ -592,7 +594,8 @@ pub fn to_expr2<'a>( // The def as a whole is a tail call iff its return expression is a tail call. // Use its output as a starting point because its tail_call already has the right answer! - let (ret_expr, mut output) = to_expr2(env, &mut scope, &loc_ret.value, loc_ret.region); + let (ret_expr, mut output) = + expr_to_expr2(env, &mut scope, &loc_ret.value, loc_ret.region); output .introduced_variables @@ -704,7 +707,7 @@ pub fn to_expr_id<'a>( parse_expr: &'a roc_parse::ast::Expr<'a>, region: Region, ) -> (ExprId, Output) { - let (expr, output) = to_expr2(env, scope, parse_expr, region); + let (expr, output) = expr_to_expr2(env, scope, parse_expr, region); (env.add(expr, region), output) } diff --git a/ast/src/lang/core/expr/mod.rs b/ast/src/lang/core/expr/mod.rs index 32d768c4c9..bb27a4ad9b 100644 --- a/ast/src/lang/core/expr/mod.rs +++ b/ast/src/lang/core/expr/mod.rs @@ -1,6 +1,6 @@ pub mod expr2; pub mod expr2_to_string; -pub(crate) mod expr_to_expr2; +pub mod expr_to_expr2; mod introduced_vars; pub(crate) mod output; pub mod record_field; diff --git a/ast/src/lang/core/str.rs b/ast/src/lang/core/str.rs index 53b0a999cf..7a939aac33 100644 --- a/ast/src/lang/core/str.rs +++ b/ast/src/lang/core/str.rs @@ -3,7 +3,7 @@ use roc_parse::ast::StrLiteral; use crate::{ ast_error::{ASTResult, UnexpectedASTNode}, - lang::{core::expr::expr_to_expr2::to_expr2, env::Env, scope::Scope}, + lang::{core::expr::expr_to_expr2::expr_to_expr2, env::Env, scope::Scope}, mem_pool::{pool::Pool, pool_str::PoolStr, pool_vec::PoolVec}, }; @@ -94,7 +94,7 @@ fn flatten_str_lines<'a>( } let (loc_expr, new_output) = - to_expr2(env, scope, loc_expr.value, loc_expr.region); + expr_to_expr2(env, scope, loc_expr.value, loc_expr.region); output.union(new_output); diff --git a/ast/src/lib.rs b/ast/src/lib.rs index b3d987f99f..092b86154e 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -3,5 +3,6 @@ mod canonicalization; pub mod constrain; pub mod lang; pub mod mem_pool; +pub mod module; pub mod parse; pub mod solve_type; diff --git a/ast/src/module.rs b/ast/src/module.rs new file mode 100644 index 0000000000..e744760c42 --- /dev/null +++ b/ast/src/module.rs @@ -0,0 +1,39 @@ +use std::path::Path; + +use bumpalo::Bump; +use roc_collections::all::MutMap; +use roc_load::file::LoadedModule; + +pub fn load_module(src_file: &Path) -> LoadedModule { + let subs_by_module = MutMap::default(); + + let arena = Bump::new(); + let loaded = roc_load::file::load_and_typecheck( + &arena, + src_file.to_path_buf(), + arena.alloc(roc_builtins::std::standard_stdlib()), + src_file.parent().unwrap_or_else(|| { + panic!( + "src_file {:?} did not have a parent directory but I need to have one.", + src_file + ) + }), + subs_by_module, + 8, + roc_can::builtins::builtin_defs_map, + ); + + match loaded { + Ok(x) => x, + Err(roc_load::file::LoadingProblem::FormattedReport(report)) => { + panic!( + "Failed to load module from src_file {:?}. Report: {:?}", + src_file, report + ); + } + Err(e) => panic!( + "Failed to load module from src_file {:?}: {:?}", + src_file, e + ), + } +} diff --git a/cli/src/lib.rs b/cli/src/lib.rs index c7b14a56f8..bfd4faea6e 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -240,7 +240,7 @@ pub fn build_app<'a>() -> App<'a> { } pub fn docs(files: Vec) { - roc_docs::generate( + roc_docs::generate_docs_html( files, roc_builtins::std::standard_stdlib(), Path::new("./generated-docs"), diff --git a/code_markup/src/markup/common_nodes.rs b/code_markup/src/markup/common_nodes.rs index 89a8a8c2d9..806d6170cd 100644 --- a/code_markup/src/markup/common_nodes.rs +++ b/code_markup/src/markup/common_nodes.rs @@ -19,7 +19,7 @@ pub fn new_comma_mn(expr_id: ExprId, parent_id_opt: Option) -> Marku MarkupNode::Text { content: nodes::COMMA.to_owned(), ast_node_id: ASTNodeId::AExprId(expr_id), - syn_high_style: HighlightStyle::Blank, + syn_high_style: HighlightStyle::Comma, attributes: Attributes::default(), parent_id_opt, newlines_at_end: 0, diff --git a/code_markup/src/markup/nodes.rs b/code_markup/src/markup/nodes.rs index cea08f288b..5243a9438b 100644 --- a/code_markup/src/markup/nodes.rs +++ b/code_markup/src/markup/nodes.rs @@ -13,7 +13,6 @@ use super::{ }; use crate::markup_error::{ExpectedTextNode, NestedNodeMissingChild, NestedNodeRequired}; -use bumpalo::Bump; use roc_ast::{ ast_error::ASTResult, lang::{ @@ -305,9 +304,8 @@ fn new_markup_node( mark_node_pool.add(node) } -pub fn def2_to_markup<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, +pub fn def2_to_markup<'a>( + env: &mut Env<'a>, def2: &Def2, def2_node_id: DefId, mark_node_pool: &mut SlowPool, @@ -321,7 +319,6 @@ pub fn def2_to_markup<'a, 'b>( expr_id, } => { let expr_mn_id = expr2_to_markup( - arena, env, env.pool.get(*expr_id), *expr_id, @@ -347,9 +344,8 @@ pub fn def2_to_markup<'a, 'b>( } // make Markup Nodes: generate String representation, assign Highlighting Style -pub fn expr2_to_markup<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, +pub fn expr2_to_markup<'a>( + env: &mut Env<'a>, expr2: &Expr2, expr2_node_id: ExprId, mark_node_pool: &mut SlowPool, @@ -380,7 +376,7 @@ pub fn expr2_to_markup<'a, 'b>( ), 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_to_markup(env, expr, *expr_id, mark_node_pool, interns)? } Expr2::Var(symbol) => { //TODO make bump_format with arena @@ -398,7 +394,6 @@ pub fn expr2_to_markup<'a, 'b>( let sub_expr2 = env.pool.get(*node_id); children_ids.push(expr2_to_markup( - arena, env, sub_expr2, *node_id, @@ -460,7 +455,6 @@ pub fn expr2_to_markup<'a, 'b>( let sub_expr2 = env.pool.get(*sub_expr2_node_id); children_ids.push(expr2_to_markup( - arena, env, sub_expr2, *sub_expr2_node_id, @@ -520,7 +514,6 @@ pub fn expr2_to_markup<'a, 'b>( expr_var: _, } => { let body_mn_id = expr2_to_markup( - arena, env, env.pool.get(*expr_id), *expr_id, @@ -797,9 +790,8 @@ fn add_header_mn_list( .collect() } -pub fn ast_to_mark_nodes<'a, 'b>( - arena: &'a Bump, - env: &mut Env<'b>, +pub fn ast_to_mark_nodes<'a>( + env: &mut Env<'a>, ast: &AST, mark_node_pool: &mut SlowPool, interns: &Interns, @@ -809,11 +801,11 @@ pub fn ast_to_mark_nodes<'a, 'b>( 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)?; + let def2_markup_id = def2_to_markup(env, def2, def_id, mark_node_pool, interns)?; - set_parent_for_all(expr2_markup_id, mark_node_pool); + set_parent_for_all(def2_markup_id, mark_node_pool); - all_mark_node_ids.push(expr2_markup_id); + all_mark_node_ids.push(def2_markup_id); } Ok(all_mark_node_ids) diff --git a/code_markup/src/syntax_highlight.rs b/code_markup/src/syntax_highlight.rs index 12c0ef33e1..dfdb32076d 100644 --- a/code_markup/src/syntax_highlight.rs +++ b/code_markup/src/syntax_highlight.rs @@ -6,6 +6,7 @@ use crate::colors::{self, from_hsb, RgbaTup}; #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug, Deserialize, Serialize)] pub enum HighlightStyle { Operator, // =+-<>... + Comma, String, FunctionName, Type, @@ -25,6 +26,7 @@ pub fn default_highlight_map() -> HashMap { let mut highlight_map = HashMap::new(); [ (Operator, colors::WHITE), + (Comma, from_hsb(258, 50, 90)), (String, from_hsb(346, 65, 97)), (FunctionName, colors::WHITE), (Type, colors::WHITE), diff --git a/compiler/can/src/scope.rs b/compiler/can/src/scope.rs index bde1032119..2a6995d717 100644 --- a/compiler/can/src/scope.rs +++ b/compiler/can/src/scope.rs @@ -83,7 +83,7 @@ impl Scope { self.idents.len() } - pub fn lookup(&mut self, ident: &Ident, region: Region) -> Result { + pub fn lookup(&self, ident: &Ident, region: Region) -> Result { match self.idents.get(ident) { Some((symbol, _)) => Ok(*symbol), None => Err(RuntimeError::LookupNotInScope( diff --git a/docs/Cargo.toml b/docs/Cargo.toml index 7cb857b8f3..883305d1e1 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -9,9 +9,12 @@ edition = "2018" [dependencies] pulldown-cmark = { version = "0.8", default-features = false } +roc_ast = { path = "../ast" } roc_load = { path = "../compiler/load" } roc_builtins = { path = "../compiler/builtins" } roc_can = { path = "../compiler/can" } +roc_code_markup = { path = "../code_markup"} +roc_fmt = { path = "../compiler/fmt" } roc_module = { path = "../compiler/module" } roc_region = { path = "../compiler/region" } roc_types = { path = "../compiler/types" } @@ -22,3 +25,5 @@ bumpalo = { version = "3.2", features = ["collections"] } [dev-dependencies] pretty_assertions = "0.5.1" maplit = "1.0.1" +tempfile = "3.2.0" +uuid = { version = "0.8", features = ["v4"] } diff --git a/docs/src/def.rs b/docs/src/def.rs new file mode 100644 index 0000000000..0c562ade25 --- /dev/null +++ b/docs/src/def.rs @@ -0,0 +1,79 @@ +use bumpalo::{collections::String as BumpString, Bump}; +use roc_ast::{ + ast_error::ASTResult, + lang::{self, core::def::def_to_def2::def_to_def2}, + mem_pool::pool::Pool, +}; +use roc_code_markup::{markup::nodes::def2_to_markup, slow_pool::SlowPool}; +use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds}; +use roc_region::all::Region; +use roc_types::subs::VarStore; + +use crate::html::mark_node_to_html; + +// html is written to buf +pub fn defs_to_html<'a>( + buf: &mut BumpString<'a>, + defs: Vec>, + env_module_id: ModuleId, + env_module_ids: &'a ModuleIds, + interns: &Interns, +) { + let mut env_pool = Pool::with_capacity(1024); + let env_arena = Bump::new(); + + let mut var_store = VarStore::default(); + let dep_idents = IdentIds::exposed_builtins(8); + let exposed_ident_ids = IdentIds::default(); + + let def_arena = Bump::new(); + + let mut env = lang::env::Env::new( + env_module_id, + &env_arena, + &mut env_pool, + &mut var_store, + dep_idents, + env_module_ids, + exposed_ident_ids, + ); + + let mut scope = lang::scope::Scope::new(env.home, env.pool, env.var_store); + let region = Region::new(0, 0, 0, 0); + + for def in defs.iter() { + // TODO remove unwrap + write_def_to_bump_str_html(&def_arena, &mut env, &mut scope, region, def, interns, buf) + .unwrap(); + } +} + +fn write_def_to_bump_str_html<'a, 'b>( + arena: &'a Bump, + env: &mut lang::env::Env<'a>, + scope: &mut lang::scope::Scope, + region: Region, + def: &'a roc_parse::ast::Def<'a>, + interns: &Interns, + buf: &mut BumpString<'b>, +) -> ASTResult<()> { + let def2 = def_to_def2(arena, env, scope, def, region); + + let def2_id = env.pool.add(def2); + + let mut mark_node_pool = SlowPool::default(); + + let def2_markup_id = def2_to_markup( + env, + env.pool.get(def2_id), + def2_id, + &mut mark_node_pool, + interns, + )?; + + let def2_markup_node = mark_node_pool.get(def2_markup_id); + + mark_node_to_html(def2_markup_node, &mark_node_pool, buf); + + Ok(()) +} diff --git a/docs/src/expr.rs b/docs/src/expr.rs new file mode 100644 index 0000000000..5651ebf056 --- /dev/null +++ b/docs/src/expr.rs @@ -0,0 +1,73 @@ +use crate::html::mark_node_to_html; +use bumpalo::{collections::String as BumpString, Bump}; +use roc_ast::{ + ast_error::ASTResult, + lang::{self, core::expr::expr_to_expr2::expr_to_expr2}, + mem_pool::pool::Pool, +}; +use roc_code_markup::{markup::nodes::expr2_to_markup, slow_pool::SlowPool}; +use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds}; +use roc_parse::ast::Expr; +use roc_region::all::Region; +use roc_types::subs::VarStore; + +// html is written to buf +pub fn expr_to_html<'a>( + buf: &mut BumpString<'a>, + expr: Expr<'a>, + env_module_id: ModuleId, + env_module_ids: &'a ModuleIds, + interns: &Interns, +) { + let mut env_pool = Pool::with_capacity(1024); + let env_arena = Bump::new(); + + let mut var_store = VarStore::default(); + let dep_idents = IdentIds::exposed_builtins(8); + let exposed_ident_ids = IdentIds::default(); + + let mut env = lang::env::Env::new( + env_module_id, + &env_arena, + &mut env_pool, + &mut var_store, + dep_idents, + env_module_ids, + exposed_ident_ids, + ); + + let mut scope = lang::scope::Scope::new(env.home, env.pool, env.var_store); + let region = Region::new(0, 0, 0, 0); + + // TODO remove unwrap + write_expr_to_bump_str_html(&mut env, &mut scope, region, &expr, interns, buf).unwrap(); +} + +fn write_expr_to_bump_str_html<'a, 'b>( + env: &mut lang::env::Env<'a>, + scope: &mut lang::scope::Scope, + region: Region, + expr: &'a Expr, + interns: &Interns, + buf: &mut BumpString<'b>, +) -> ASTResult<()> { + let (expr2, _) = expr_to_expr2(env, scope, expr, region); + + let expr2_id = env.pool.add(expr2); + + let mut mark_node_pool = SlowPool::default(); + + let expr2_markup_id = expr2_to_markup( + env, + env.pool.get(expr2_id), + expr2_id, + &mut mark_node_pool, + interns, + )?; + + let expr2_markup_node = mark_node_pool.get(expr2_markup_id); + + mark_node_to_html(expr2_markup_node, &mark_node_pool, buf); + + Ok(()) +} diff --git a/docs/src/html.rs b/docs/src/html.rs new file mode 100644 index 0000000000..4a85663970 --- /dev/null +++ b/docs/src/html.rs @@ -0,0 +1,80 @@ +use bumpalo::collections::String as BumpString; +use roc_code_markup::{markup::nodes::MarkupNode, slow_pool::SlowPool}; + +// determine appropriate css class for MarkupNode +pub fn mark_node_to_html<'a>( + mark_node: &MarkupNode, + mark_node_pool: &SlowPool, + buf: &mut BumpString<'a>, +) { + let additional_newlines: usize; + + match mark_node { + MarkupNode::Nested { + children_ids, + newlines_at_end, + .. + } => { + for &child_id in children_ids { + mark_node_to_html(mark_node_pool.get(child_id), mark_node_pool, buf) + } + + additional_newlines = *newlines_at_end; + } + MarkupNode::Text { + content, + syn_high_style, + newlines_at_end, + .. + } => { + use roc_code_markup::syntax_highlight::HighlightStyle::*; + + let css_class = match syn_high_style { + Operator => "operator", + Comma => "comma", + String => "string", + FunctionName => "function_name", + Type => "type", + Bracket => "bracket", + Number => "number", + PackageRelated => "package-related", + Variable => "variable", + RecordField => "recordfield", + Import => "import", + Provides => "provides", + Blank => "blank", + }; + + write_html_to_buf(content, css_class, buf); + + additional_newlines = *newlines_at_end; + } + MarkupNode::Blank { + newlines_at_end, .. + } => { + let mut content_str = " ".to_string(); + + for _ in 0..*newlines_at_end { + content_str.push('\n'); + } + + write_html_to_buf(&content_str, "blank", buf); + + additional_newlines = *newlines_at_end; + } + } + + for _ in 0..additional_newlines { + buf.push('\n') + } +} + +fn write_html_to_buf<'a>(content: &str, css_class: &'static str, buf: &mut BumpString<'a>) { + let opening_tag: String = [""].concat(); + + buf.push_str(opening_tag.as_str()); + + buf.push_str(content); + + buf.push_str(""); +} diff --git a/docs/src/lib.rs b/docs/src/lib.rs index b317ac2fee..1565fb6527 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -1,6 +1,8 @@ extern crate pulldown_cmark; extern crate roc_load; -use bumpalo::Bump; +use bumpalo::{collections::String as BumpString, collections::Vec as BumpVec, Bump}; +use def::defs_to_html; +use expr::expr_to_html; use roc_builtins::std::StdLib; use roc_can::builtins::builtin_defs_map; use roc_can::scope::Scope; @@ -9,15 +11,19 @@ use roc_load::docs::DocEntry::DocDef; use roc_load::docs::{DocEntry, TypeAnnotation}; use roc_load::docs::{ModuleDocumentation, RecordField}; use roc_load::file::{LoadedModule, LoadingProblem}; -use roc_module::symbol::{IdentIds, Interns, ModuleId}; +use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds}; use roc_parse::ident::{parse_ident, Ident}; -use roc_parse::parser::State; +use roc_parse::parser::{State, SyntaxError}; use roc_region::all::Region; use std::fs; use std::path::{Path, PathBuf}; -pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { - let files_docs = files_to_documentations(filenames, std_lib); +mod def; +mod expr; +mod html; + +pub fn generate_docs_html(filenames: Vec, std_lib: StdLib, build_dir: &Path) { + let loaded_modules = load_modules_for_files(filenames, std_lib); let mut arena = Bump::new(); // @@ -26,7 +32,7 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { name: "roc/builtins".to_string(), version: "1.0.0".to_string(), docs: "Package introduction or README.".to_string(), - modules: files_docs, + modules: loaded_modules, }; if !build_dir.exists() { @@ -53,11 +59,11 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { .expect("TODO gracefully handle failing to make the favicon"); let template_html = include_str!("./static/index.html") - .replace("", &format!("{}search.js", base_href())) - .replace("", &format!("{}styles.css", base_href())) + .replace("", &format!("{}search.js", base_url())) + .replace("", &format!("{}styles.css", base_url())) .replace( "", - &format!("{}favicon.svg", base_href()), + &format!("{}favicon.svg", base_url()), ) .replace( "", @@ -79,8 +85,8 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { for loaded_module in package.modules.iter_mut() { arena.reset(); - let mut exports: bumpalo::collections::Vec<&str> = - bumpalo::collections::Vec::with_capacity_in(loaded_module.exposed_values.len(), &arena); + let mut exports: BumpVec<&str> = + BumpVec::with_capacity_in(loaded_module.exposed_values.len(), &arena); // TODO should this also include exposed_aliases? for symbol in loaded_module.exposed_values.iter() { @@ -89,8 +95,8 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { let exports = exports.into_bump_slice(); - for module in loaded_module.documentation.values_mut() { - let module_dir = build_dir.join(module.name.replace(".", "/").as_str()); + for module_docs in loaded_module.documentation.values() { + let module_dir = build_dir.join(module_docs.name.replace(".", "/").as_str()); fs::create_dir_all(&module_dir) .expect("TODO gracefully handle not being able to create the module dir"); @@ -103,14 +109,7 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { ) .replace( "", - render_main_content( - loaded_module.module_id, - exports, - &loaded_module.dep_idents, - &loaded_module.interns, - module, - ) - .as_str(), + render_module_documentation(exports, module_docs, loaded_module).as_str(), ); fs::write(module_dir.join("index.html"), rendered_module) @@ -121,20 +120,63 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { println!("🎉 Docs generated in {}", build_dir.display()); } -fn render_main_content( - home: ModuleId, - exposed_values: &[&str], - dep_idents: &MutMap, +// converts plain-text code to highlighted html +pub fn syntax_highlight_expr<'a>( + arena: &'a Bump, + buf: &mut BumpString<'a>, + code_str: &'a str, + env_module_id: ModuleId, + env_module_ids: &'a ModuleIds, interns: &Interns, - module: &mut ModuleDocumentation, +) -> Result> { + let trimmed_code_str = code_str.trim_end().trim(); + let state = State::new(trimmed_code_str.as_bytes()); + + match roc_parse::expr::test_parse_expr(0, arena, state) { + Ok(loc_expr) => { + expr_to_html(buf, loc_expr.value, env_module_id, env_module_ids, interns); + + Ok(buf.to_string()) + } + Err(fail) => Err(SyntaxError::Expr(fail)), + } +} + +// converts plain-text code to highlighted html +pub fn syntax_highlight_top_level_defs<'a>( + arena: &'a Bump, + buf: &mut BumpString<'a>, + code_str: &'a str, + env_module_id: ModuleId, + env_module_ids: &'a ModuleIds, + interns: &Interns, +) -> Result> { + let trimmed_code_str = code_str.trim_end().trim(); + + match roc_parse::test_helpers::parse_defs_with(arena, trimmed_code_str) { + Ok(vec_loc_def) => { + let vec_def = vec_loc_def.iter().map(|loc| loc.value).collect(); + + defs_to_html(buf, vec_def, env_module_id, env_module_ids, interns); + + Ok(buf.to_string()) + } + Err(err) => Err(err), + } +} + +fn render_module_documentation( + exposed_values: &[&str], + module: &ModuleDocumentation, + loaded_module: &LoadedModule, ) -> String { let mut buf = String::new(); buf.push_str( - html_node( + html_to_string( "h2", vec![("class", "module-name")], - html_node("a", vec![("href", "/#")], module.name.as_str()).as_str(), + html_to_string("a", vec![("href", "/#")], module.name.as_str()).as_str(), ) .as_str(), ); @@ -158,7 +200,9 @@ fn render_main_content( let mut content = String::new(); - content.push_str(html_node("a", vec![("href", href.as_str())], name).as_str()); + content.push_str( + html_to_string("a", vec![("href", href.as_str())], name).as_str(), + ); for type_var in &doc_def.type_vars { content.push(' '); @@ -177,7 +221,7 @@ fn render_main_content( type_annotation_to_html(0, &mut content, type_ann); buf.push_str( - html_node( + html_to_string( "h3", vec![("id", name), ("class", "entry-name")], content.as_str(), @@ -188,12 +232,10 @@ fn render_main_content( if let Some(docs) = &doc_def.docs { buf.push_str( markdown_to_html( - home, exposed_values, - dep_idents, - &mut module.scope, - interns, + &module.scope, docs.to_string(), + loaded_module, ) .as_str(), ); @@ -201,12 +243,10 @@ fn render_main_content( } DocEntry::DetachedDoc(docs) => { let markdown = markdown_to_html( - home, exposed_values, - dep_idents, - &mut module.scope, - interns, + &module.scope, docs.to_string(), + loaded_module, ); buf.push_str(markdown.as_str()); } @@ -217,7 +257,7 @@ fn render_main_content( buf } -fn html_node(tag_name: &str, attrs: Vec<(&str, &str)>, content: &str) -> String { +fn html_to_string(tag_name: &str, attrs: Vec<(&str, &str)>, content: &str) -> String { let mut buf = String::new(); buf.push('<'); @@ -246,62 +286,62 @@ fn html_node(tag_name: &str, attrs: Vec<(&str, &str)>, content: &str) -> String buf } -fn base_href() -> String { +fn base_url() -> String { // e.g. "builtins/" in "https://roc-lang.org/builtins/Str" // // TODO make this a CLI flag to the `docs` subcommand instead of an env var match std::env::var("ROC_DOCS_URL_ROOT") { Ok(root_builtins_path) => { - let mut href = String::with_capacity(root_builtins_path.len() + 64); + let mut url_str = String::with_capacity(root_builtins_path.len() + 64); if !root_builtins_path.starts_with('/') { - href.push('/'); + url_str.push('/'); } - href.push_str(&root_builtins_path); + url_str.push_str(&root_builtins_path); if !root_builtins_path.ends_with('/') { - href.push('/'); + url_str.push('/'); } - href + url_str } _ => { - let mut href = String::with_capacity(64); + let mut url_str = String::with_capacity(64); - href.push('/'); + url_str.push('/'); - href + url_str } } } fn render_name_and_version(name: &str, version: &str) -> String { let mut buf = String::new(); - let mut href = base_href(); + let mut url_str = base_url(); - href.push_str(name); + url_str.push_str(name); buf.push_str( - html_node( + html_to_string( "h1", vec![("class", "pkg-full-name")], - html_node("a", vec![("href", href.as_str())], name).as_str(), + html_to_string("a", vec![("href", url_str.as_str())], name).as_str(), ) .as_str(), ); - let mut versions_href = base_href(); + let mut versions_url_str = base_url(); - versions_href.push('/'); - versions_href.push_str(name); - versions_href.push('/'); - versions_href.push_str(version); + versions_url_str.push('/'); + versions_url_str.push_str(name); + versions_url_str.push('/'); + versions_url_str.push_str(version); buf.push_str( - html_node( + html_to_string( "a", - vec![("class", "version"), ("href", versions_href.as_str())], + vec![("class", "version"), ("href", versions_url_str.as_str())], version, ) .as_str(), @@ -321,13 +361,13 @@ fn render_sidebar<'a, I: Iterator, &'a ModuleDocumentation)> let name = module.name.as_str(); let href = { - let mut href_buf = base_href(); + let mut href_buf = base_url(); href_buf.push_str(name); href_buf }; sidebar_entry_content.push_str( - html_node( + html_to_string( "a", vec![("class", "sidebar-module-link"), ("href", href.as_str())], name, @@ -348,7 +388,7 @@ fn render_sidebar<'a, I: Iterator, &'a ModuleDocumentation)> entry_href.push_str(doc_def.name.as_str()); entries_buf.push_str( - html_node( + html_to_string( "a", vec![("href", entry_href.as_str())], doc_def.name.as_str(), @@ -363,7 +403,7 @@ fn render_sidebar<'a, I: Iterator, &'a ModuleDocumentation)> }; sidebar_entry_content.push_str( - html_node( + html_to_string( "div", vec![("class", "sidebar-sub-entries")], entries.as_str(), @@ -372,7 +412,7 @@ fn render_sidebar<'a, I: Iterator, &'a ModuleDocumentation)> ); buf.push_str( - html_node( + html_to_string( "div", vec![("class", "sidebar-entry")], sidebar_entry_content.as_str(), @@ -384,9 +424,9 @@ fn render_sidebar<'a, I: Iterator, &'a ModuleDocumentation)> buf } -pub fn files_to_documentations(filenames: Vec, std_lib: StdLib) -> Vec { +pub fn load_modules_for_files(filenames: Vec, std_lib: StdLib) -> Vec { let arena = Bump::new(); - let mut files_docs = vec![]; + let mut modules = vec![]; for filename in filenames { let mut src_dir = filename.clone(); @@ -401,7 +441,7 @@ pub fn files_to_documentations(filenames: Vec, std_lib: StdLib) -> Vec< std::mem::size_of::() as u32, // This is just type-checking for docs, so "target" doesn't matter builtin_defs_map, ) { - Ok(loaded) => files_docs.push(loaded), + Ok(loaded) => modules.push(loaded), Err(LoadingProblem::FormattedReport(report)) => { println!("{}", report); panic!(); @@ -410,7 +450,7 @@ pub fn files_to_documentations(filenames: Vec, std_lib: StdLib) -> Vec< } } - files_docs + modules } const INDENT: &str = " "; @@ -425,6 +465,7 @@ fn new_line(buf: &mut String) { buf.push('\n'); } +// html is written to buf fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &TypeAnnotation) { let is_multiline = should_be_multiline(type_ann); match type_ann { @@ -686,7 +727,7 @@ fn doc_url<'a>( home: ModuleId, exposed_values: &[&str], dep_idents: &MutMap, - scope: &mut Scope, + scope: &Scope, interns: &'a Interns, mut module_name: &'a str, ident: &str, @@ -753,7 +794,7 @@ fn doc_url<'a>( } } - let mut url = base_href(); + let mut url = base_url(); // Example: // @@ -769,12 +810,10 @@ fn doc_url<'a>( } fn markdown_to_html( - home: ModuleId, exposed_values: &[&str], - dep_idents: &MutMap, - scope: &mut Scope, - interns: &Interns, + scope: &Scope, markdown: String, + loaded_module: &LoadedModule, ) -> String { use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Tag::*}; @@ -801,11 +840,11 @@ fn markdown_to_html( match iter.next() { Some(symbol_name) if iter.next().is_none() => { let DocUrl { url, title } = doc_url( - home, + loaded_module.module_id, exposed_values, - dep_idents, + &loaded_module.dep_idents, scope, - interns, + &loaded_module.interns, module_name, symbol_name, ); @@ -824,11 +863,11 @@ fn markdown_to_html( // This looks like a global tag name, but it could // be a type alias that's in scope, e.g. [I64] let DocUrl { url, title } = doc_url( - home, + loaded_module.module_id, exposed_values, - dep_idents, + &loaded_module.dep_idents, scope, - interns, + &loaded_module.interns, "", type_name, ); @@ -843,6 +882,9 @@ fn markdown_to_html( }; let markdown_options = pulldown_cmark::Options::empty(); + + let mut expecting_code_block = false; + let mut docs_parser = vec![]; let (_, _) = pulldown_cmark::Parser::new_with_broken_link_callback( &markdown, @@ -850,6 +892,7 @@ fn markdown_to_html( Some(&mut broken_link_callback), ) .fold((0, 0), |(start_quote_count, end_quote_count), event| { + match &event { // Replace this sequence (`>>>` syntax): // Start(BlockQuote) @@ -915,6 +958,39 @@ fn markdown_to_html( (start_quote_count, end_quote_count) } + Event::Start(CodeBlock(CodeBlockKind::Fenced(_))) => { + expecting_code_block = true; + docs_parser.push(event); + (0, 0) + } + Event::End(CodeBlock(_)) => { + expecting_code_block = false; + docs_parser.push(event); + (0, 0) + } + Event::Text(CowStr::Borrowed(code_str)) if expecting_code_block => { + let code_block_arena = Bump::new(); + + let mut code_block_buf = BumpString::new_in(&code_block_arena); + match syntax_highlight_expr( + &code_block_arena, + &mut code_block_buf, + code_str, + loaded_module.module_id, + &loaded_module.interns.module_ids, + &loaded_module.interns + ) + { + Ok(highlighted_code_str) => { + docs_parser.push(Event::Html(CowStr::from(highlighted_code_str))); + } + Err(syntax_error) => { + panic!("Unexpected parse failure when parsing this for rendering in docs:\n\n{}\n\nParse error was:\n\n{:?}\n\n", code_str, syntax_error) + } + }; + + (0, 0) + } _ => { docs_parser.push(event); (0, 0) diff --git a/docs/src/static/index.html b/docs/src/static/index.html index 48ffc31509..8a1ea794e8 100644 --- a/docs/src/static/index.html +++ b/docs/src/static/index.html @@ -41,7 +41,7 @@

Made by people who like to make nice things.

-

© 2020

+

© 2021

diff --git a/docs/src/static/styles.css b/docs/src/static/styles.css index e78db71ea6..799d849a86 100644 --- a/docs/src/static/styles.css +++ b/docs/src/static/styles.css @@ -7,7 +7,6 @@ --body-bg-color: #fdfdfd; --border-color: #e9e9e9; --faded-color: #4c4c4c; - --monospace-font; --font-sans: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif; --font-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; --top-header-height: 67px; @@ -283,7 +282,6 @@ code { font-family: var(--font-mono); color: var(--code-color); background-color: var(--code-bg-color); - padding: 2px 8px; display: inline-block; } @@ -306,15 +304,34 @@ pre { overflow-x: auto; } -pre code { - padding: 6px 8px; -} - .hidden { /* Use !important to win all specificity fights. */ display: none !important; } +.syntax-number { + color: #60B7BF; +} +.syntax-string { + color:#F7577C; +} + +.syntax-bracket { + color:#FF335F; +} +.syntax-closure-dash, +.syntax-closure-arrow, +.syntax-operator +{ + color: #ffffff; +} +.syntax-comma { + color: #9573E6; +} +.syntax-comment { + color: #ff0000; +} + #module-search:placeholder-shown { padding: 0; opacity: 0; diff --git a/docs/tests/insert_syntax_highlighting.rs b/docs/tests/insert_syntax_highlighting.rs new file mode 100644 index 0000000000..a031fbb07b --- /dev/null +++ b/docs/tests/insert_syntax_highlighting.rs @@ -0,0 +1,158 @@ +#[macro_use] +extern crate pretty_assertions; + +#[cfg(test)] +mod insert_doc_syntax_highlighting { + use std::{fs::File, io::Write, path::PathBuf}; + + use bumpalo::{collections::String as BumpString, Bump}; + use roc_ast::module::load_module; + use roc_docs::{syntax_highlight_expr, syntax_highlight_top_level_defs}; + use roc_load::file::LoadedModule; + use tempfile::tempdir; + use uuid::Uuid; + + fn expect_html(code_str: &str, want: &str, use_expr: bool) { + let loaded_module = make_mock_module(); + + let code_block_arena = Bump::new(); + let mut code_block_buf = BumpString::new_in(&code_block_arena); + + if use_expr { + match syntax_highlight_expr( + &code_block_arena, + &mut code_block_buf, + code_str, + loaded_module.module_id, + &loaded_module.interns.module_ids, + &loaded_module.interns, + ) { + Ok(highlighted_code_str) => { + assert_eq!(highlighted_code_str, want); + } + Err(syntax_error) => { + panic!("Unexpected parse failure when parsing this for rendering in docs:\n\n{}\n\nParse error was:\n\n{:?}\n\n", code_str, syntax_error) + } + }; + } else { + match syntax_highlight_top_level_defs( + &code_block_arena, + &mut code_block_buf, + code_str, + loaded_module.module_id, + &loaded_module.interns.module_ids, + &loaded_module.interns, + ) { + Ok(highlighted_code_str) => { + assert_eq!(highlighted_code_str, want); + } + Err(syntax_error) => { + panic!("Unexpected parse failure when parsing this for rendering in docs:\n\n{}\n\nParse error was:\n\n{:?}\n\n", code_str, syntax_error) + } + }; + } + } + + pub const HELLO_WORLD: &str = r#" +app "test-app" + packages { base: "platform" } + imports [] + provides [ main ] to base + +main = "Hello, world!" + + +"#; + + fn make_mock_module() -> LoadedModule { + let temp_dir = tempdir().expect("Failed to create temporary directory for test."); + let temp_file_path_buf = + PathBuf::from([Uuid::new_v4().to_string(), ".roc".to_string()].join("")); + let temp_file_full_path = temp_dir.path().join(temp_file_path_buf); + + let mut file = File::create(temp_file_full_path.clone()).expect(&format!( + "Failed to create temporary file for path {:?}", + temp_file_full_path + )); + writeln!(file, "{}", HELLO_WORLD).expect(&format!( + "Failed to write {:?} to file: {:?}", + HELLO_WORLD, file + )); + + load_module(&temp_file_full_path) + } + + fn expect_html_expr(code_str: &str, want: &str) { + expect_html(code_str, want, true) + } + + fn expect_html_def(code_str: &str, want: &str) { + expect_html(code_str, want, false) + } + + #[test] + fn number_expr() { + expect_html_expr("2", r#"2"#); + } + + #[test] + fn string_expr() { + expect_html_expr(r#""abc""#, r#""abc""#); + } + + #[test] + fn empty_list_expr() { + expect_html_expr( + r#"[]"#, + r#"[ ]"#, + ); + } + + #[test] + fn single_elt_list_expr() { + expect_html_expr( + r#"[ 0 ]"#, + r#"[ 0 ]"#, + ); + } + + #[test] + fn multi_elt_list_expr() { + expect_html_expr( + r#"[ "hello", "WoRlD" ]"#, + r#"[ "hello", "WoRlD" ]"#, + ); + } + + #[test] + fn record_expr() { + expect_html_expr( + r#"{ a: "hello!" }"#, + "{ a: \"hello!\" }", + ); + } + + #[test] + fn nested_record_expr() { + expect_html_expr( + r#"{ a: { bB: "WoRlD" } }"#, + "{ a: { bB: \"WoRlD\" } }", + ); + } + + #[test] + fn top_level_def_value() { + expect_html_def( + r#"main = "Hello, World!""#, + "main = \"Hello, World!\"\n\n", + ); + } + + #[test] + fn tld_list() { + expect_html_def( + r#"main = [ 1, 2, 3 ]"#, + "main = [ 1, 2, 3 ]\n\n", + ); + } +} diff --git a/editor/src/editor/main.rs b/editor/src/editor/main.rs index 3e93c5c35f..8e37429fae 100644 --- a/editor/src/editor/main.rs +++ b/editor/src/editor/main.rs @@ -25,10 +25,7 @@ use fs_extra::dir::{copy, ls, CopyOptions, DirEntryAttr, DirEntryValue}; use pipelines::RectResources; use roc_ast::lang::env::Env; use roc_ast::mem_pool::pool::Pool; -use roc_can::builtins::builtin_defs_map; -use roc_collections::all::MutMap; -use roc_load; -use roc_load::file::LoadedModule; +use roc_ast::module::load_module; use roc_module::symbol::IdentIds; use roc_types::subs::VarStore; use std::collections::HashSet; @@ -557,40 +554,6 @@ fn copy_roc_platform_if_not_exists( } } -pub fn load_module(src_file: &Path) -> LoadedModule { - let subs_by_module = MutMap::default(); - - let arena = Bump::new(); - let loaded = roc_load::file::load_and_typecheck( - &arena, - src_file.to_path_buf(), - arena.alloc(roc_builtins::std::standard_stdlib()), - src_file.parent().unwrap_or_else(|| { - panic!( - "src_file {:?} did not have a parent directory but I need to have one.", - src_file - ) - }), - subs_by_module, - 8, - builtin_defs_map, - ); - - match loaded { - Ok(x) => x, - Err(roc_load::file::LoadingProblem::FormattedReport(report)) => { - panic!( - "Failed to load module from src_file {:?}. Report: {:?}", - src_file, report - ); - } - Err(e) => panic!( - "Failed to load module from src_file {:?}: {:?}", - src_file, e - ), - } -} - fn queue_no_file_text( size: &PhysicalSize, text: &str, diff --git a/editor/src/editor/mvc/ed_model.rs b/editor/src/editor/mvc/ed_model.rs index d255bdbeb5..8d7f85db20 100644 --- a/editor/src/editor/mvc/ed_model.rs +++ b/editor/src/editor/mvc/ed_model.rs @@ -63,7 +63,6 @@ pub fn init_model<'a>( EmptyCodeString {}.fail() } else { Ok(ast_to_mark_nodes( - code_arena, &mut module.env, &module.ast, &mut mark_node_pool, @@ -199,7 +198,6 @@ impl<'a> EdModule<'a> { #[cfg(test)] pub mod test_ed_model { use crate::editor::ed_error::EdResult; - use crate::editor::main::load_module; use crate::editor::mvc::ed_model; use crate::editor::resources::strings::HELLO_WORLD; use crate::ui::text::caret_w_select::test_caret_w_select::convert_dsl_to_selection; @@ -212,6 +210,7 @@ pub mod test_ed_model { use ed_model::EdModel; use roc_ast::lang::env::Env; use roc_ast::mem_pool::pool::Pool; + use roc_ast::module::load_module; use roc_load::file::LoadedModule; use roc_module::symbol::IdentIds; use roc_module::symbol::ModuleIds; diff --git a/www/public/styles.css b/www/public/styles.css index b90cfb58a2..3d1a47ec35 100644 --- a/www/public/styles.css +++ b/www/public/styles.css @@ -282,7 +282,6 @@ code { font-family: var(--font-mono); color: var(--code-color); background-color: var(--code-bg-color); - padding: 0 8px; display: inline-block; line-height: 28px; } @@ -303,15 +302,15 @@ pre { overflow-x: auto; } -pre code { - padding: 6px 8px; -} - .hidden { /* Use !important to win all specificity fights. */ display: none !important; } +.syntax-comment { + color: #ff0000; +} + #module-search:placeholder-shown { padding: 0; opacity: 0;