mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
assertion failed solved_all
This commit is contained in:
parent
d922d72d83
commit
db4f788076
7 changed files with 89 additions and 59 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -25,9 +25,8 @@ editor/benches/resources/25000000_lines.roc
|
|||
editor/benches/resources/50000_lines.roc
|
||||
editor/benches/resources/500_lines.roc
|
||||
|
||||
# file editor creates when none is selected
|
||||
UntitledApp.roc
|
||||
NewRocProject
|
||||
# file editor creates when no arg is passed
|
||||
new-roc-project
|
||||
|
||||
# rust cache (sccache folder)
|
||||
sccache_dir
|
||||
|
|
|
@ -28,7 +28,7 @@ fn main() -> io::Result<()> {
|
|||
}
|
||||
|
||||
None => {
|
||||
launch_editor(&[])?;
|
||||
launch_editor(None)?;
|
||||
|
||||
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)
|
||||
.unwrap()
|
||||
.values_of_os(DIRECTORY_OR_FILES)
|
||||
.map(|mut values| values.next())
|
||||
{
|
||||
None => {
|
||||
launch_editor(&[])?;
|
||||
Some(Some(os_str)) => {
|
||||
launch_editor(Some(&Path::new(os_str)))?;
|
||||
}
|
||||
Some(values) => {
|
||||
let paths = values
|
||||
.map(|os_str| Path::new(os_str))
|
||||
.collect::<Vec<&Path>>();
|
||||
|
||||
launch_editor(&paths)?;
|
||||
_ => {
|
||||
launch_editor(None)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,8 +153,8 @@ fn roc_files_recursive<P: AsRef<Path>>(
|
|||
}
|
||||
|
||||
#[cfg(feature = "editor")]
|
||||
fn launch_editor(filepaths: &[&Path]) -> io::Result<()> {
|
||||
roc_editor::launch(filepaths)
|
||||
fn launch_editor(project_dir_path: Option<&Path>) -> io::Result<()> {
|
||||
roc_editor::launch(project_dir_path)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "editor"))]
|
||||
|
|
|
@ -1949,6 +1949,7 @@ fn update<'a>(
|
|||
}
|
||||
|
||||
if module_id == state.root_id && state.goal_phase == Phase::SolveTypes {
|
||||
dbg!(&state);
|
||||
debug_assert!(work.is_empty());
|
||||
debug_assert!(state.dependencies.solved_all());
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ use crate::graphics::{
|
|||
use crate::lang::expr::Env;
|
||||
use crate::lang::pool::Pool;
|
||||
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 cgmath::Vector2;
|
||||
use fs_extra::dir::{CopyOptions, copy};
|
||||
use fs_extra::dir::{CopyOptions, DirEntryAttr, DirEntryValue, copy, ls};
|
||||
use pipelines::RectResources;
|
||||
use roc_can::builtins::builtin_defs_map;
|
||||
use roc_collections::all::MutMap;
|
||||
|
@ -31,6 +31,7 @@ use roc_load;
|
|||
use roc_load::file::LoadedModule;
|
||||
use roc_module::symbol::IdentIds;
|
||||
use roc_types::subs::VarStore;
|
||||
use std::collections::HashSet;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
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,
|
||||
/// or if you provide it 1 or more files or directories to open on launch.
|
||||
pub fn launch(filepaths: &[&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
|
||||
};
|
||||
pub fn launch(project_dir_path_opt: Option<&Path>) -> io::Result<()> {
|
||||
|
||||
run_event_loop(first_path_opt).expect("Error running event loop");
|
||||
run_event_loop(project_dir_path_opt).expect("Error running event loop");
|
||||
|
||||
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();
|
||||
|
||||
// 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 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 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) {
|
||||
if let Some(file_path) = file_path_opt {
|
||||
let file_as_str = std::fs::read_to_string(file_path)
|
||||
.unwrap_or_else(|_| panic!("Failed to read from provided file path: {:?}", file_path));
|
||||
type PathStr = String;
|
||||
|
||||
(file_path, file_as_str)
|
||||
fn read_main_roc_file(project_dir_path_opt: Option<&Path>) -> (PathStr, String) {
|
||||
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 {
|
||||
init_new_roc_project()
|
||||
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)
|
||||
}
|
||||
|
||||
} else {
|
||||
init_new_roc_project("new-roc-project")
|
||||
}
|
||||
}
|
||||
|
||||
// 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 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(){
|
||||
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);
|
||||
|
||||
(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?"#,
|
||||
orig_platform_path
|
||||
);
|
||||
} else {
|
||||
} else if !project_platform_path.exists() {
|
||||
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,
|
||||
I tried to copy the platform at {:?} to {:?} but it failed: {}"#,
|
||||
|
|
|
@ -551,8 +551,10 @@ impl<'a> EdModel<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn replace_selected_expr_with_blank(&mut self) -> EdResult<()> {
|
||||
let expr_mark_node_id_opt = if let Some(sel_block) = &self.selected_block_opt {
|
||||
// Replaces selected expression with blank.
|
||||
// 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 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)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let expr_mark_node_id = sel_block.mark_node_id;
|
||||
|
||||
// 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();
|
||||
|
||||
EdModel::insert_between_line(
|
||||
|
@ -598,9 +595,11 @@ impl<'a> EdModel<'a> {
|
|||
&mut self.grid_node_map,
|
||||
&mut self.code_lines,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.set_sel_none();
|
||||
} else {
|
||||
self.select_expr()?;
|
||||
};
|
||||
|
||||
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 macOS '\u{7f}'.
|
||||
|
||||
ed_model.replace_selected_expr_with_blank()?;
|
||||
ed_model.backspace()?;
|
||||
|
||||
InputOutcome::Accepted
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ impl AppHeader {
|
|||
// TODO don't use mock struct and actually parse string
|
||||
pub fn parse_from_string(_header_str: &str, ast_node_id: ExprId) -> Self {
|
||||
AppHeader {
|
||||
app_name: "\"untitled_app\"".to_owned(),
|
||||
app_name: "\"untitled-app\"".to_owned(),
|
||||
packages_base: "\"platform\"".to_owned(),
|
||||
imports: vec![],
|
||||
provides: vec!["main".to_owned()],
|
||||
|
|
|
@ -17,6 +17,6 @@ mod window;
|
|||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn launch(filepaths: &[&Path]) -> io::Result<()> {
|
||||
editor::main::launch(filepaths)
|
||||
pub fn launch(project_dir_path_opt: Option<&Path>) -> io::Result<()> {
|
||||
editor::main::launch(project_dir_path_opt)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue