assertion failed solved_all

This commit is contained in:
Anton-4 2021-09-09 16:55:30 +02:00
parent d922d72d83
commit db4f788076
7 changed files with 89 additions and 59 deletions

5
.gitignore vendored
View file

@ -25,9 +25,8 @@ editor/benches/resources/25000000_lines.roc
editor/benches/resources/50000_lines.roc editor/benches/resources/50000_lines.roc
editor/benches/resources/500_lines.roc editor/benches/resources/500_lines.roc
# file editor creates when none is selected # file editor creates when no arg is passed
UntitledApp.roc new-roc-project
NewRocProject
# rust cache (sccache folder) # rust cache (sccache folder)
sccache_dir sccache_dir

View file

@ -28,7 +28,7 @@ fn main() -> io::Result<()> {
} }
None => { None => {
launch_editor(&[])?; launch_editor(None)?;
Ok(0) Ok(0)
} }
@ -60,16 +60,13 @@ If you're building the compiler from source you'll want to do `cargo run [FILE]`
.subcommand_matches(CMD_EDIT) .subcommand_matches(CMD_EDIT)
.unwrap() .unwrap()
.values_of_os(DIRECTORY_OR_FILES) .values_of_os(DIRECTORY_OR_FILES)
.map(|mut values| values.next())
{ {
None => { Some(Some(os_str)) => {
launch_editor(&[])?; launch_editor(Some(&Path::new(os_str)))?;
} }
Some(values) => { _ => {
let paths = values launch_editor(None)?;
.map(|os_str| Path::new(os_str))
.collect::<Vec<&Path>>();
launch_editor(&paths)?;
} }
} }
@ -156,8 +153,8 @@ fn roc_files_recursive<P: AsRef<Path>>(
} }
#[cfg(feature = "editor")] #[cfg(feature = "editor")]
fn launch_editor(filepaths: &[&Path]) -> io::Result<()> { fn launch_editor(project_dir_path: Option<&Path>) -> io::Result<()> {
roc_editor::launch(filepaths) roc_editor::launch(project_dir_path)
} }
#[cfg(not(feature = "editor"))] #[cfg(not(feature = "editor"))]

View file

@ -1949,6 +1949,7 @@ fn update<'a>(
} }
if module_id == state.root_id && state.goal_phase == Phase::SolveTypes { if module_id == state.root_id && state.goal_phase == Phase::SolveTypes {
dbg!(&state);
debug_assert!(work.is_empty()); debug_assert!(work.is_empty());
debug_assert!(state.dependencies.solved_all()); debug_assert!(state.dependencies.solved_all());

View file

@ -20,10 +20,10 @@ use crate::graphics::{
use crate::lang::expr::Env; use crate::lang::expr::Env;
use crate::lang::pool::Pool; use crate::lang::pool::Pool;
use crate::ui::text::caret_w_select::CaretPos; use crate::ui::text::caret_w_select::CaretPos;
use crate::ui::util::slice_get; use crate::ui::util::path_to_string;
use bumpalo::Bump; use bumpalo::Bump;
use cgmath::Vector2; use cgmath::Vector2;
use fs_extra::dir::{CopyOptions, copy}; use fs_extra::dir::{CopyOptions, DirEntryAttr, DirEntryValue, copy, ls};
use pipelines::RectResources; use pipelines::RectResources;
use roc_can::builtins::builtin_defs_map; use roc_can::builtins::builtin_defs_map;
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
@ -31,6 +31,7 @@ use roc_load;
use roc_load::file::LoadedModule; use roc_load::file::LoadedModule;
use roc_module::symbol::IdentIds; use roc_module::symbol::IdentIds;
use roc_types::subs::VarStore; use roc_types::subs::VarStore;
use std::collections::HashSet;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::Write; use std::io::Write;
use std::{error::Error, io, path::Path}; use std::{error::Error, io, path::Path};
@ -52,26 +53,14 @@ use winit::{
/// The editor is actually launched from the CLI if you pass it zero arguments, /// The editor is actually launched from the CLI if you pass it zero arguments,
/// or if you provide it 1 or more files or directories to open on launch. /// or if you provide it 1 or more files or directories to open on launch.
pub fn launch(filepaths: &[&Path]) -> io::Result<()> { pub fn launch(project_dir_path_opt: Option<&Path>) -> io::Result<()> {
//TODO support using multiple filepaths
let first_path_opt = if !filepaths.is_empty() {
match slice_get(0, filepaths) {
Ok(path_ref_ref) => Some(*path_ref_ref),
Err(e) => {
eprintln!("{}", e);
None
}
}
} else {
None
};
run_event_loop(first_path_opt).expect("Error running event loop"); run_event_loop(project_dir_path_opt).expect("Error running event loop");
Ok(()) Ok(())
} }
fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> { fn run_event_loop(project_dir_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
env_logger::init(); env_logger::init();
// Open window and create a surface // Open window and create a surface
@ -138,9 +127,12 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
let env_arena = Bump::new(); let env_arena = Bump::new();
let code_arena = Bump::new(); let code_arena = Bump::new();
let (file_path, code_str) = read_file(file_path_opt); let (file_path_str, code_str) = read_main_roc_file(project_dir_path_opt);
println!("Loading file {}...", file_path_str);
let loaded_module = load_module(file_path); let file_path = Path::new(&file_path_str);
let loaded_module = load_module(&file_path);
let mut var_store = VarStore::default(); let mut var_store = VarStore::default();
let dep_idents = IdentIds::exposed_builtins(8); let dep_idents = IdentIds::exposed_builtins(8);
@ -404,27 +396,69 @@ fn begin_render_pass<'a>(
}) })
} }
fn read_file(file_path_opt: Option<&Path>) -> (&Path, String) { type PathStr = String;
if let Some(file_path) = file_path_opt {
let file_as_str = std::fs::read_to_string(file_path) fn read_main_roc_file(project_dir_path_opt: Option<&Path>) -> (PathStr, String) {
.unwrap_or_else(|_| panic!("Failed to read from provided file path: {:?}", file_path)); if let Some(project_dir_path) = project_dir_path_opt {
let mut ls_config = HashSet::new();
ls_config.insert(DirEntryAttr::FullName);
let dir_items = ls(project_dir_path, &ls_config)
.unwrap_or_else(|err| panic!("Failed to list items in project directory: {:?}", err))
.items;
let file_names_2d: Vec<Vec<&String>> =
dir_items
.iter()
.map(|info_hash_map| info_hash_map.values().map(
|dir_entry_value|
if let DirEntryValue::String(file_name) = dir_entry_value {
Some(file_name)
} else {
None
}
)
.filter_map(|x| x) // remove None
.collect())
.collect();
let roc_file_names: Vec<&String> =
file_names_2d
.into_iter()
.flatten()
.filter(|file_name| file_name.contains(".roc"))
.collect();
let project_dir_path_str = path_to_string(project_dir_path);
if let Some(&roc_file_name) = roc_file_names.first() {
let full_roc_file_path_str = vec![project_dir_path_str.clone(), "/".to_owned(), roc_file_name.clone()].join("");
let file_as_str = std::fs::read_to_string(&Path::new(&full_roc_file_path_str))
.unwrap_or_else(|err| panic!("In the provided project {:?}, I found the roc file {}, but I failed to read it: {}", &project_dir_path_str, &full_roc_file_path_str, err));
(full_roc_file_path_str, file_as_str)
} else {
init_new_roc_project(&project_dir_path_str)
}
(file_path, file_as_str)
} else { } else {
init_new_roc_project() init_new_roc_project("new-roc-project")
} }
} }
// returns path and content of app file // returns path and content of app file
fn init_new_roc_project() -> (&'static Path, String) { fn init_new_roc_project(project_dir_path_str: &str) -> (PathStr, String) {
let orig_platform_path = Path::new("./examples/hello-world/platform"); let orig_platform_path = Path::new("./examples/hello-world/platform");
let project_dir_path = Path::new("./NewRocProject"); let project_dir_path = Path::new(project_dir_path_str);
let roc_file_path = Path::new("./NewRocProject/UntitledApp.roc"); let roc_file_path_str = vec![project_dir_path_str, "/UntitledApp.roc"].join("");
let roc_file_path = Path::new("./new-roc-project/UntitledApp.roc");
let project_platform_path = Path::new("./NewRocProject/platform"); let project_platform_path_str = vec![project_dir_path_str, "/platform"].join("");
let project_platform_path = Path::new(&project_platform_path_str);
if !project_dir_path.exists(){ if !project_dir_path.exists(){
fs::create_dir(project_dir_path).expect("Failed to create dir for roc project."); fs::create_dir(project_dir_path).expect("Failed to create dir for roc project.");
@ -434,7 +468,7 @@ fn init_new_roc_project() -> (&'static Path, String) {
let code_str = create_roc_file_if_not_exists(project_dir_path, roc_file_path); let code_str = create_roc_file_if_not_exists(project_dir_path, roc_file_path);
(roc_file_path, code_str) (roc_file_path_str, code_str)
} }
@ -476,7 +510,7 @@ fn copy_roc_platform_if_not_exists(orig_platform_path: &Path, project_platform_p
Are you at the root of the roc repository?"#, Are you at the root of the roc repository?"#,
orig_platform_path orig_platform_path
); );
} else { } else if !project_platform_path.exists() {
copy(orig_platform_path, project_dir_path, &CopyOptions::new()).unwrap_or_else(|err|{ copy(orig_platform_path, project_dir_path, &CopyOptions::new()).unwrap_or_else(|err|{
panic!(r#"No roc file path was passed to the editor, so I wanted to create a new roc project and roc projects require a platform, panic!(r#"No roc file path was passed to the editor, so I wanted to create a new roc project and roc projects require a platform,
I tried to copy the platform at {:?} to {:?} but it failed: {}"#, I tried to copy the platform at {:?} to {:?} but it failed: {}"#,

View file

@ -551,8 +551,10 @@ impl<'a> EdModel<'a> {
} }
} }
fn replace_selected_expr_with_blank(&mut self) -> EdResult<()> { // Replaces selected expression with blank.
let expr_mark_node_id_opt = if let Some(sel_block) = &self.selected_block_opt { // If no expression is selected, this function will select one to guide the user to using backspace in a projectional editing way
fn backspace(&mut self) -> EdResult<()> {
if let Some(sel_block) = &self.selected_block_opt {
let expr2_level_mark_node = self.mark_node_pool.get(sel_block.mark_node_id); let expr2_level_mark_node = self.mark_node_pool.get(sel_block.mark_node_id);
let newlines_at_end = expr2_level_mark_node.get_newlines_at_end(); let newlines_at_end = expr2_level_mark_node.get_newlines_at_end();
@ -581,13 +583,8 @@ impl<'a> EdModel<'a> {
} }
} }
Some(sel_block.mark_node_id) let expr_mark_node_id = sel_block.mark_node_id;
} else {
None
};
// have to split the previous `if` up to prevent borrowing issues
if let Some(expr_mark_node_id) = expr_mark_node_id_opt {
let caret_pos = self.get_caret(); let caret_pos = self.get_caret();
EdModel::insert_between_line( EdModel::insert_between_line(
@ -598,9 +595,11 @@ impl<'a> EdModel<'a> {
&mut self.grid_node_map, &mut self.grid_node_map,
&mut self.code_lines, &mut self.code_lines,
)?; )?;
}
self.set_sel_none(); self.set_sel_none();
} else {
self.select_expr()?;
};
Ok(()) Ok(())
} }
@ -1120,7 +1119,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
// On Linux, '\u{8}' is backspace, // On Linux, '\u{8}' is backspace,
// on macOS '\u{7f}'. // on macOS '\u{7f}'.
ed_model.replace_selected_expr_with_blank()?; ed_model.backspace()?;
InputOutcome::Accepted InputOutcome::Accepted
} }

View file

@ -88,7 +88,7 @@ impl AppHeader {
// TODO don't use mock struct and actually parse string // TODO don't use mock struct and actually parse string
pub fn parse_from_string(_header_str: &str, ast_node_id: ExprId) -> Self { pub fn parse_from_string(_header_str: &str, ast_node_id: ExprId) -> Self {
AppHeader { AppHeader {
app_name: "\"untitled_app\"".to_owned(), app_name: "\"untitled-app\"".to_owned(),
packages_base: "\"platform\"".to_owned(), packages_base: "\"platform\"".to_owned(),
imports: vec![], imports: vec![],
provides: vec!["main".to_owned()], provides: vec!["main".to_owned()],

View file

@ -17,6 +17,6 @@ mod window;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
pub fn launch(filepaths: &[&Path]) -> io::Result<()> { pub fn launch(project_dir_path_opt: Option<&Path>) -> io::Result<()> {
editor::main::launch(filepaths) editor::main::launch(project_dir_path_opt)
} }