Skip to content

Commit

Permalink
Merge branch 'develop' into compiler/wip/mk/dataflow-warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
kustosz authored Feb 2, 2022
2 parents 4ab1702 + b6cf6b9 commit dc59c1f
Show file tree
Hide file tree
Showing 35 changed files with 1,726 additions and 226 deletions.
7 changes: 7 additions & 0 deletions app/gui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#### Visual Environment

- [New nodes can be created by dragging and dropping a connection on the
scene.][3231]
- [Node connections can be dropped by pressing the Esc key while dragging
them.][3231]
- [Added support of source maps for JS-based visualizations.][3208]
- [Fixed histograms coloring and added a color legend.][3153]
- [Fixed broken node whose expression contains non-ASCII characters.][3166]
Expand All @@ -23,6 +27,7 @@
`Vector.filter_with_index`. Made `Vector.at` accept negative indices and
ensured it fails with a dataflow error on out of bounds access instead of an
internal Java exception.][3232]
- [Implemented the `Table.select_columns` operation.][3230]

[3153]: https://github.com/enso-org/enso/pull/3153
[3166]: https://github.com/enso-org/enso/pull/3166
Expand All @@ -32,7 +37,9 @@
[3208]: https://github.com/enso-org/enso/pull/3208
[3224]: https://github.com/enso-org/enso/pull/3224
[3229]: https://github.com/enso-org/enso/pull/3229
[3231]: https://github.com/enso-org/enso/pull/3231
[3232]: https://github.com/enso-org/enso/pull/3232
[3230]: https://github.com/enso-org/enso/pull/3230

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
1 change: 1 addition & 0 deletions app/gui/docs/product/shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ broken and require further investigation.
| <kbd>alt</kbd>+<kbd>F4</kbd> | Close the application (MacOS, Windows, Linux) |
| <kbd>ctrl</kbd>+<kbd>w</kbd> | Close the application (Windows, Linux) |
| :warning: <kbd>ctrl</kbd>+<kbd>p</kbd> | Toggle profiling mode |
| <kbd>escape</kbd> | Cancel current action. For example, drop currently dragged connection. |

#### Navigation

Expand Down
45 changes: 21 additions & 24 deletions app/gui/src/controller/searcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,11 @@ impl Display for ParsedInput {

/// Information about a node that is used as a `this` argument.
///
/// When searcher is brought up with a node selected, the node will be used as "this". This affects
/// suggestions for the first completion (to include methods of the node's returned value) and the
/// code inserted when the input is committed.
/// "This" node is either:
/// 1. A node that was selected when the searcher was brought up.
/// 2. A source node of the connection that was dropped on the scene to create a new node.
/// This affects suggestions for the first completion (to include methods of the node's returned
/// value) and the code inserted when the input is committed.
#[derive(Clone, Debug)]
pub struct ThisNode {
/// Identifier of the node that will be connected if the initial suggestion is picked.
Expand All @@ -318,15 +320,11 @@ pub struct ThisNode {
}

impl ThisNode {
/// Retrieve information about the `self` node. The first selected node will be used for this.
/// Retrieve information about the `self` node.
///
/// Returns `None` if the given node's information cannot be retrieved or if the node does not
/// introduce a variable.
pub fn new(
nodes: Vec<double_representation::node::Id>,
graph: &controller::Graph,
) -> Option<Self> {
let id = *nodes.first()?;
pub fn new(id: double_representation::node::Id, graph: &controller::Graph) -> Option<Self> {
let node = graph.node(id).ok()?;
let (var, needs_to_introduce_pattern) = if let Some(ast) = node.info.pattern() {
// TODO [mwu]
Expand Down Expand Up @@ -364,8 +362,9 @@ impl ThisNode {
#[derive(Copy, Clone, Debug)]
#[allow(missing_docs)]
pub enum Mode {
/// Searcher should add a new node at given position.
NewNode { position: Option<Position> },
/// Searcher should add a new node at a given position. `source_node` is either a selected node
/// or a node from which the connection was dragged out before being dropped at the scene.
NewNode { position: Option<Position>, source_node: Option<ast::Id> },
/// Searcher should edit existing node's expression.
EditNode { node_id: ast::Id },
}
Expand Down Expand Up @@ -488,10 +487,9 @@ impl Searcher {
project: &model::Project,
method: language_server::MethodPointer,
mode: Mode,
selected_nodes: Vec<double_representation::node::Id>,
) -> FallibleResult<Self> {
let graph = controller::ExecutedGraph::new(&parent, project.clone_ref(), method).await?;
Self::new_from_graph_controller(parent, ide, project, graph, mode, selected_nodes)
Self::new_from_graph_controller(parent, ide, project, graph, mode)
}

/// Create new Searcher Controller, when you have Executed Graph Controller handy.
Expand All @@ -501,7 +499,6 @@ impl Searcher {
project: &model::Project,
graph: controller::ExecutedGraph,
mode: Mode,
selected_nodes: Vec<double_representation::node::Id>,
) -> FallibleResult<Self> {
let project = project.clone_ref();
let logger = Logger::new_sub(parent, "Searcher Controller");
Expand All @@ -521,10 +518,10 @@ impl Searcher {
let def_span = double_representation::module::definition_span(&module_ast, &def_id)?;
let module_repr: enso_text::Text = module_ast.repr().into();
let position = module_repr.location_of_byte_offset_snapped(def_span.end);
let this_arg = Rc::new(
matches!(mode, Mode::NewNode { .. })
.and_option_from(|| ThisNode::new(selected_nodes, &graph.graph())),
);
let this_arg = Rc::new(match mode {
Mode::NewNode { source_node: Some(node), .. } => ThisNode::new(node, &graph.graph()),
_ => None,
});
let ret = Self {
logger,
graph,
Expand Down Expand Up @@ -657,7 +654,7 @@ impl Searcher {
self.commit_node().map(Some)
}
Action::Example(example) => match *self.mode {
Mode::NewNode { position } => self.add_example(&example, position).map(Some),
Mode::NewNode { position, .. } => self.add_example(&example, position).map(Some),
_ => Err(CannotExecuteWhenEditingNode.into()),
},
Action::ProjectManagement(action) => {
Expand Down Expand Up @@ -739,7 +736,7 @@ impl Searcher {
// We add the required imports before we create the node/edit its content. This way, we
// avoid an intermediate state where imports would already be in use but not yet available.
match *self.mode {
Mode::NewNode { position } => {
Mode::NewNode { position, .. } => {
self.add_required_imports()?;
let (expression, intended_method) = expr_and_method();
let metadata = NodeMetadata { position, intended_method, ..default() };
Expand Down Expand Up @@ -1257,7 +1254,7 @@ pub mod test {
let code_range = enso_text::Location::default()..=end_of_code;
let graph = data.graph.controller();
let node = &graph.graph().nodes().unwrap()[0];
let this = ThisNode::new(vec![node.info.id()], &graph.graph());
let this = ThisNode::new(node.info.id(), &graph.graph());
let this = data.selected_node.and_option(this);
let logger = Logger::new("Searcher"); // new_empty
let database = Rc::new(SuggestionDatabase::new_empty(&logger));
Expand All @@ -1283,7 +1280,7 @@ pub mod test {
ide: Rc::new(ide),
data: default(),
notifier: default(),
mode: Immutable(Mode::NewNode { position: default() }),
mode: Immutable(Mode::NewNode { position: default(), source_node: None }),
language_server: language_server::Connection::new_mock_rc(client),
this_arg: Rc::new(this),
position_in_code: Immutable(end_of_code),
Expand Down Expand Up @@ -1854,7 +1851,7 @@ pub mod test {
});

// Add new node.
searcher.mode = Immutable(Mode::NewNode { position: None });
searcher.mode = Immutable(Mode::NewNode { position: None, source_node: None });
searcher.commit_node().unwrap();

let module_info = module.info();
Expand Down Expand Up @@ -1892,7 +1889,7 @@ pub mod test {

// Add new node.
let position = Some(Position::new(4.0, 5.0));
searcher.mode = Immutable(Mode::NewNode { position });
searcher.mode = Immutable(Mode::NewNode { position, source_node: None });
searcher.commit_node().unwrap();

let expected_code =
Expand Down
14 changes: 7 additions & 7 deletions app/gui/src/presenter/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
use crate::prelude::*;

use crate::presenter;

use crate::executor::global::spawn_stream_handler;
use crate::presenter;
use crate::presenter::graph::ViewNodeId;

use enso_frp as frp;
use ide_view as view;
use ide_view::project::ComponentBrowserOpenReason;


// =============
Expand Down Expand Up @@ -64,15 +65,15 @@ impl Model {
}
}

fn setup_searcher_presenter(&self, node_view: ViewNodeId) {
fn setup_searcher_presenter(&self, way_of_opening_searcher: ComponentBrowserOpenReason) {
let new_presenter = presenter::Searcher::setup_controller(
&self.logger,
self.ide_controller.clone_ref(),
self.controller.clone_ref(),
self.graph_controller.clone_ref(),
&self.graph,
self.view.clone_ref(),
node_view,
way_of_opening_searcher,
);
match new_presenter {
Ok(searcher) => {
Expand Down Expand Up @@ -184,9 +185,8 @@ impl Project {
let graph_view = &model.view.graph().frp;

frp::extend! { network
searcher_input <- view.searcher_input.filter_map(|view| *view);
eval searcher_input ((node_view) {
model.setup_searcher_presenter(*node_view)
eval view.searcher_opened ((way_of_opening_searcher) {
model.setup_searcher_presenter(*way_of_opening_searcher)
});

graph_view.remove_node <+ view.editing_committed.filter_map(f!([model]((node_view, entry)) {
Expand Down
38 changes: 29 additions & 9 deletions app/gui/src/presenter/searcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ use crate::executor::global::spawn_stream_handler;
use crate::presenter;
use crate::presenter::graph::AstNodeId;
use crate::presenter::graph::ViewNodeId;

use enso_frp as frp;
use ide_view as view;
use ide_view::graph_editor::component::node as node_view;
use ide_view::project::ComponentBrowserOpenReason;



Expand Down Expand Up @@ -151,30 +153,29 @@ impl Searcher {
graph_controller: controller::ExecutedGraph,
graph_presenter: &presenter::Graph,
view: view::project::View,
node_view: ViewNodeId,
way_of_opening_searcher: ComponentBrowserOpenReason,
) -> FallibleResult<Self> {
let ast_node = graph_presenter.ast_node_of_view(node_view);
let id = way_of_opening_searcher.node();
let ast_node = graph_presenter.ast_node_of_view(id);
let mode = match ast_node {
Some(node_id) => controller::searcher::Mode::EditNode { node_id },
None => {
let view_data = view.graph().model.nodes.get_cloned_ref(&node_view);
let view_data = view.graph().model.nodes.get_cloned_ref(&id);
let position = view_data.map(|node| node.position().xy());
let position = position.map(|vector| model::module::Position { vector });
controller::searcher::Mode::NewNode { position }
let source_node =
Self::source_node_ast_id(&view, graph_presenter, &way_of_opening_searcher);
controller::searcher::Mode::NewNode { position, source_node }
}
};
let selected_views = view.graph().model.nodes.all_selected();
let selected_nodes =
selected_views.iter().filter_map(|view| graph_presenter.ast_node_of_view(*view));
let searcher_controller = controller::Searcher::new_from_graph_controller(
&parent,
ide_controller,
&project_controller.model,
graph_controller,
mode,
selected_nodes.collect(),
)?;
Ok(Self::new(parent, searcher_controller, view, node_view))
Ok(Self::new(parent, searcher_controller, view, id))
}

/// Commit editing.
Expand All @@ -201,4 +202,23 @@ impl Searcher {
let entry = controller.actions().list().and_then(|l| l.get_cloned(entry));
entry.map_or(false, |e| matches!(e.action, Example(_)))
}

/// Return the AST id of the source node. Source node is either:
/// 1. The source node of the connection that was dropped to create a node.
/// 2. The first of the selected nodes on the scene.
fn source_node_ast_id(
view: &view::project::View,
graph_presenter: &presenter::Graph,
way_of_opening_searcher: &ComponentBrowserOpenReason,
) -> Option<Uuid> {
if let Some(edge_id) = way_of_opening_searcher.edge() {
let edge = view.graph().model.edges.get_cloned_ref(&edge_id);
let edge_source = edge.map(|edge| edge.source()).flatten();
let source_node_id = edge_source.map(|source| source.node_id);
source_node_id.map(|id| graph_presenter.ast_node_of_view(id)).flatten()
} else {
let selected_views = view.graph().model.nodes.all_selected();
selected_views.iter().find_map(|view| graph_presenter.ast_node_of_view(*view))
}
}
}
5 changes: 2 additions & 3 deletions app/gui/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,15 +296,14 @@ pub mod mock {
);
let executor = TestWithLocalPoolExecutor::set_up();
let data = self.clone();
let selected_nodes = Vec::new();
let searcher_mode = controller::searcher::Mode::NewNode { position: None };
let searcher_mode =
controller::searcher::Mode::NewNode { position: None, source_node: None };
let searcher = controller::Searcher::new_from_graph_controller(
&logger,
ide.clone_ref(),
&project,
executed_graph.clone_ref(),
searcher_mode,
selected_nodes,
)
.unwrap();
Fixture {
Expand Down
Loading

0 comments on commit dc59c1f

Please sign in to comment.