mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +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/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
|
||||||
|
|
|
@ -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"))]
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
.unwrap_or_else(|_| panic!("Failed to read from provided file path: {:?}", file_path));
|
|
||||||
|
|
||||||
(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 {
|
} 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
|
// 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: {}"#,
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()],
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue