Skip to content

Commit

Permalink
Merge branch 'develop' into wip/procrat/node-action-bar-tooltips-5933
Browse files Browse the repository at this point in the history
* develop:
  Layout fixes (#6066)
  Use new Enso Hash Codes and Comparable (#6060)
  Search suggestions by static attribute (#6036)
  Use .node-version for pinning Node.js version (#6057)
  Fix code generation for suggestion preview (#6054)
  Implementation of EnsoGL predefined Rectangle shape. (#6033)
  Tidy up the public module level statics (#6032)
  Cursor aware Component Browser (#5770)
  • Loading branch information
Procrat committed Mar 27, 2023
2 parents dd1fc03 + 866a58a commit 8b203e6
Show file tree
Hide file tree
Showing 124 changed files with 3,660 additions and 2,692 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Cargo.toml
# GUI
/app/gui/ @MichaelMauderer @wdanilo @farmaazon @mwu-tow @kazcw
/app/gui/view/ @MichaelMauderer @wdanilo @farmaazon @kazcw
/app/gui/view/graph-editor/src/builtin/visualization/java_script/ @MichaelMauderer @wdanilo @farmaazon @kazcw @jdunkerley
/app/ide-desktop/ @MichaelMauderer @wdanilo @kazcw

# Engine (old)
Expand Down
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18.14.1
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 2 additions & 7 deletions app/gui/controller/double-representation/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ impl Info {
}
}

/// Obtain the qualified name of the module.
/// Return the module path as [`QualifiedName`]. Returns [`Err`] if the path is not a valid
/// module name.
pub fn qualified_module_name(&self) -> FallibleResult<QualifiedName> {
QualifiedName::from_all_segments(&self.module)
}
Expand Down Expand Up @@ -108,12 +109,6 @@ impl Info {
self.hash(&mut hasher);
hasher.finish()
}

/// Return the module path as [`QualifiedName`]. Returns [`Err`] if the path is not a valid
/// module name.
pub fn module_qualified_name(&self) -> FallibleResult<QualifiedName> {
QualifiedName::from_all_segments(self.module.iter())
}
}

impl Display for Info {
Expand Down
1 change: 1 addition & 0 deletions app/gui/controller/engine-protocol/src/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ trait API {
, self_type : Option<String>
, return_type : Option<String>
, tags : Option<Vec<SuggestionEntryType>>
, is_static : Option<bool>
) -> response::Completion;

/// Get the list of component groups available in runtime.
Expand Down
8 changes: 4 additions & 4 deletions app/gui/docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ setup:
[the latest LTS version of node and npm](https://nodejs.org/en/download). Even
minor release changes are known to cause serious issues, thus **we provide
support for the latest LTS version only. Please do not report build issues if
you use other versions.** In case you run macOS or Linux the easiest way to
set up the proper version is by installing the
[Node Version Manager](https://github.com/nvm-sh/nvm) and running
`nvm install --lts && nvm use --lts`.
you use other versions.** The easiest way to set up the proper version is by
installing
[a Node version manager that automatically picks up the correct version](https://github.com/shadowspawn/node-version-usage#supporting-products),
like [fnm](https://github.com/Schniz/fnm).

- **(Optional) FlatBuffer compiler `flatc`**

Expand Down
2 changes: 1 addition & 1 deletion app/gui/language/ast/impl/src/crumbs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ pub trait TraversableAst: Sized {
/// Recursively traverses AST to retrieve AST node located by given crumbs sequence.
fn get_traversing(&self, crumbs: &[Crumb]) -> FallibleResult<&Ast>;

/// Get the `Ast` node corresponging to `Self`.
/// Get the `Ast` node corresponding to `Self`.
fn my_ast(&self) -> FallibleResult<&Ast> {
self.get_traversing(&[])
}
Expand Down
9 changes: 5 additions & 4 deletions app/gui/language/ast/impl/src/opr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,11 @@ impl Chain {
while !self.args.is_empty() {
self.fold_arg()
}
// TODO[ao] the only case when target is none is when chain have None target and empty
// arguments list. Such Chain cannot be generated from Ast, but someone could think that
// this is still a valid chain. To consider returning error here.
self.target.unwrap().arg
if let Some(target) = self.target {
target.arg
} else {
SectionSides { opr: self.operator.into() }.into()
}
}

/// True if all operands are set, i.e. there are no section shapes in this chain.
Expand Down
3 changes: 3 additions & 0 deletions app/gui/language/ast/impl/src/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub const RAW_BLOCK_QUOTES: &str = "\"\"\"";
/// Quotes opening block of the formatted text.
pub const FMT_BLOCK_QUOTES: &str = "'''";

/// A list of possible delimiters of the text literals.
pub const STRING_DELIMITERS: &[&str] = &[RAW_BLOCK_QUOTES, FMT_BLOCK_QUOTES, "\"", "'"];



// =============
Expand Down
140 changes: 31 additions & 109 deletions app/gui/src/controller/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use engine_protocol::language_server;
use parser::Parser;
use span_tree::action::Action;
use span_tree::action::Actions;
use span_tree::generate::context::CalledMethodInfo;
use span_tree::generate::Context as SpanTreeContext;
use span_tree::SpanTree;

Expand Down Expand Up @@ -790,6 +789,20 @@ impl Handle {
module::locate(&module_ast, &self.id)
}

/// The span of the definition of this graph in the module's AST.
pub fn definition_span(&self) -> FallibleResult<enso_text::Range<enso_text::Byte>> {
let def = self.definition()?;
self.module.ast().range_of_descendant_at(&def.crumbs)
}

/// The location of the last byte of the definition of this graph in the module's AST.
pub fn definition_end_location(&self) -> FallibleResult<enso_text::Location<enso_text::Byte>> {
let module_ast = self.module.ast();
let module_repr: enso_text::Rope = module_ast.repr().into();
let def_span = self.definition_span()?;
Ok(module_repr.offset_to_location_snapped(def_span.end))
}

/// Updates the AST of the definition of this graph.
#[profile(Debug)]
pub fn update_definition_ast<F>(&self, f: F) -> FallibleResult
Expand Down Expand Up @@ -1023,24 +1036,6 @@ impl Handle {
}
}


// === Span Tree Context ===

/// Span Tree generation context for a graph that does not know about execution.
///
/// It just applies the information from the metadata.
impl span_tree::generate::Context for Handle {
fn call_info(&self, id: node::Id, name: Option<&str>) -> Option<CalledMethodInfo> {
let db = &self.suggestion_db;
let metadata = self.module.node_metadata(id).ok()?;
let db_entry = db.lookup_method(metadata.intended_method?)?;
// If the name is different than intended method than apparently it is not intended anymore
// and should be ignored.
let matching = if let Some(name) = name { name == db_entry.name } else { true };
matching.then(|| db_entry.invocation_info(db, &self.parser))
}
}

impl model::undo_redo::Aware for Handle {
fn undo_redo_repository(&self) -> Rc<model::undo_redo::Repository> {
self.module.undo_redo_repository()
Expand Down Expand Up @@ -1069,15 +1064,11 @@ pub mod tests {
use engine_protocol::language_server::MethodPointer;
use enso_text::index::*;
use parser::Parser;
use span_tree::generate::MockContext;



/// Returns information about all the connections between graph's nodes.
///
/// Will use `self` as the context for span tree generation.
pub fn connections(graph: &Handle) -> FallibleResult<Connections> {
graph.connections(graph)
graph.connections(&span_tree::generate::context::Empty)
}

/// All the data needed to set up and run the graph controller in mock environment.
Expand Down Expand Up @@ -1253,45 +1244,6 @@ main =
})
}

#[test]
fn span_tree_context_handling_metadata_and_name() {
let entry = crate::test::mock::data::suggestion_entry_foo();
let mut test = Fixture::set_up();
test.data.suggestions.insert(0, entry.clone());
test.data.code = "main = bar".to_owned();
test.run(|graph| async move {
let nodes = graph.nodes().unwrap();
assert_eq!(nodes.len(), 1);
let id = nodes[0].info.id();
graph
.module
.set_node_metadata(id, NodeMetadata {
intended_method: entry.method_id(),
..default()
})
.unwrap();

let get_invocation_info = || {
let node = &graph.nodes().unwrap()[0];
assert_eq!(node.info.id(), id);
let expression = node.info.expression().repr();
graph.call_info(id, Some(expression.as_str()))
};

// Now node is `bar` while the intended method is `foo`.
// No invocation should be reported, as the name is mismatched.
assert!(get_invocation_info().is_none());

// Now the name should be good and we should the information about node being a call.
graph.set_expression(id, &entry.name).unwrap();
crate::test::assert_call_info(get_invocation_info().unwrap(), &entry);

// Now we remove metadata, so the information is no more.
graph.module.remove_node_metadata(id).unwrap();
assert!(get_invocation_info().is_none());
})
}

#[test]
fn graph_controller_used_names_in_inline_def() {
let mut test = Fixture::set_up();
Expand Down Expand Up @@ -1751,7 +1703,6 @@ main =
struct Case {
dest_node_expr: &'static str,
dest_node_expected: &'static str,
info: Option<CalledMethodInfo>,
}


Expand All @@ -1763,57 +1714,28 @@ main =
let expected = format!("{}{}", MAIN_PREFIX, self.dest_node_expected);
let this = self.clone();
test.run(|graph| async move {
let error_message = format!("{this:?}");
let ctx = match this.info.clone() {
Some(info) => {
let nodes = graph.nodes().expect(&error_message);
let dest_node_id = nodes.last().expect(&error_message).id();
MockContext::new_single(dest_node_id, info)
}
None => MockContext::default(),
};
let connections = graph.connections(&ctx).expect(&error_message);
let connection = connections.connections.first().expect(&error_message);
graph.disconnect(connection, &ctx).expect(&error_message);
let new_main = graph.definition().expect(&error_message).ast.repr();
assert_eq!(new_main, expected, "{error_message}");
let connections = connections(&graph).unwrap();
let connection = connections.connections.first().unwrap();
graph.disconnect(connection, &span_tree::generate::context::Empty).unwrap();
let new_main = graph.definition().unwrap().ast.repr();
assert_eq!(new_main, expected, "Case {this:?}");
})
}
}

let info = || {
Some(CalledMethodInfo {
parameters: vec![
span_tree::ArgumentInfo::named("arg1"),
span_tree::ArgumentInfo::named("arg2"),
span_tree::ArgumentInfo::named("arg3"),
],
..default()
})
};

#[rustfmt::skip]
let cases = &[
Case { info: None, dest_node_expr: "var + a", dest_node_expected: "_ + a" },
Case { info: None, dest_node_expr: "a + var", dest_node_expected: "a + _" },
Case { info: None, dest_node_expr: "var + b + c", dest_node_expected: "b + c" },
Case { info: None, dest_node_expr: "a + var + c", dest_node_expected: "a + c" },
Case { info: None, dest_node_expr: "a + b + var", dest_node_expected: "a + b" },
Case { info: None, dest_node_expr: "foo var", dest_node_expected: "foo _" },
Case { info: None, dest_node_expr: "foo var a", dest_node_expected: "foo a" },
Case { info: None, dest_node_expr: "foo a var", dest_node_expected: "foo a" },
Case { info: info(), dest_node_expr: "foo var", dest_node_expected: "foo" },
Case { info: info(), dest_node_expr: "foo var a", dest_node_expected: "foo arg2=a" },
Case { info: info(), dest_node_expr: "foo a var", dest_node_expected: "foo a" },
Case { info: info(), dest_node_expr: "foo arg2=var a", dest_node_expected: "foo a" },
Case { info: info(), dest_node_expr: "foo arg1=var a", dest_node_expected: "foo arg2=a" },
Case {
info: info(),
dest_node_expr: "foo arg2=var a c",
dest_node_expected: "foo a arg3=c"
},
Case { dest_node_expr: "var + a", dest_node_expected: "_ + a" },
Case { dest_node_expr: "a + var", dest_node_expected: "a + _" },
Case { dest_node_expr: "var + b + c", dest_node_expected: "b + c" },
Case { dest_node_expr: "a + var + c", dest_node_expected: "a + c" },
Case { dest_node_expr: "a + b + var", dest_node_expected: "a + b" },
Case { dest_node_expr: "foo var", dest_node_expected: "foo _" },
Case { dest_node_expr: "foo var a", dest_node_expected: "foo a" },
Case { dest_node_expr: "foo a var", dest_node_expected: "foo a" },
Case { dest_node_expr: "foo arg2=var a", dest_node_expected: "foo a" },
Case { dest_node_expr: "foo arg1=var a", dest_node_expected: "foo a" },
Case { dest_node_expr: "foo arg2=var a c", dest_node_expected: "foo a c" },
Case {
info: None,
dest_node_expr: "f\n bar a var",
dest_node_expected: "f\n bar a _",
},
Expand Down
Loading

0 comments on commit 8b203e6

Please sign in to comment.