Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lookup method pointers in IDE #5578

Merged
merged 18 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ pub struct ExpressionUpdate {
pub expression_id: ExpressionId,
#[serde(rename = "type")] // To avoid collision with the `type` keyword.
pub typename: Option<String>,
pub method_pointer: Option<SuggestionId>,
pub method_pointer: Option<MethodPointer>,
pub profiling_info: Vec<ProfilingInfo>,
pub from_cache: bool,
pub payload: ExpressionUpdatePayload,
Expand Down Expand Up @@ -1250,7 +1250,7 @@ pub mod test {
/// method pointer.
pub fn value_update_with_method_ptr(
id: ExpressionId,
method_pointer: SuggestionId,
method_pointer: MethodPointer,
) -> ExpressionUpdate {
ExpressionUpdate {
expression_id: id,
Expand Down
27 changes: 15 additions & 12 deletions app/gui/src/controller/graph/executed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use crate::prelude::*;

use crate::model::execution_context::ComponentGroup;
use crate::model::execution_context::ComputedValueInfo;
use crate::model::execution_context::ComputedValueInfoRegistry;
use crate::model::execution_context::LocalCall;
use crate::model::execution_context::QualifiedMethodPointer;
Expand Down Expand Up @@ -231,18 +232,17 @@ impl Handle {
Ok(())
}

/// Attempts to get the method pointer of the specified node.
/// Attempts to get the computed value of the specified node.
///
/// Fails if there's no information about target method pointer (e.g. because node value hasn't
/// been yet computed by the engine).
pub fn node_method_pointer(
/// Fails if there's no information e.g. because node value hasn't been yet computed by the
/// engine.
pub fn node_computed_value(
&self,
node: double_representation::node::Id,
) -> FallibleResult<Rc<MethodPointer>> {
) -> FallibleResult<Rc<ComputedValueInfo>> {
let registry = self.execution_ctx.computed_value_info_registry();
let node_info = registry.get(&node).ok_or(NotEvaluatedYet(node))?;
let entry_id = *node_info.method_call.as_ref().ok_or(NoResolvedMethod(node))?;
self.project.suggestion_db().lookup_method_ptr(entry_id).map(Rc::new)
Ok(node_info)
}

/// Enter node by given ID.
Expand All @@ -254,8 +254,9 @@ impl Handle {
/// been yet computed by the engine) or if method graph cannot be created (see
/// `graph_for_method` documentation).
pub async fn enter_node(&self, node: double_representation::node::Id) -> FallibleResult {
let definition = self.node_method_pointer(node)?;
let definition = (*definition).clone();
let computed_value = self.node_computed_value(node)?;
let method_pointer = computed_value.method_call.as_ref().ok_or(NoResolvedMethod(node))?;
let definition = method_pointer.clone();
let local_call = LocalCall { call: node, definition };
self.enter_method_pointer(&local_call).await
}
Expand Down Expand Up @@ -336,8 +337,9 @@ impl Handle {
impl Context for Handle {
fn call_info(&self, id: ast::Id, name: Option<&str>) -> Option<CalledMethodInfo> {
let lookup_registry = || {
let method_call = self.computed_value_info_registry().get_method_call(&id)?;
let entry = self.project.suggestion_db().lookup(method_call).ok()?;
let info = self.computed_value_info_registry().get(&id)?;
let method_call = info.method_call.as_ref()?;
let entry = self.project.suggestion_db().lookup_by_method_pointer(method_call)?;
Some(entry.invocation_info())
};
let fallback = || self.graph.borrow().call_info(id, name);
Expand Down Expand Up @@ -480,7 +482,8 @@ pub mod tests {

// Now send update that expression actually was computed to be a call to the second
// suggestion entry and check that executed graph provides this info over the metadata one.
let update = value_update_with_method_ptr(id, 2);
let method_pointer = entry2.clone().try_into().unwrap();
let update = value_update_with_method_ptr(id, method_pointer);
executed_graph.computed_value_info_registry().apply_updates(vec![update]);
let info = get_invocation_info().unwrap();
assert_call_info(info, &entry2);
Expand Down
8 changes: 1 addition & 7 deletions app/gui/src/model/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use engine_protocol::language_server;
use engine_protocol::language_server::ExpressionUpdate;
use engine_protocol::language_server::ExpressionUpdatePayload;
use engine_protocol::language_server::MethodPointer;
use engine_protocol::language_server::SuggestionId;
use engine_protocol::language_server::VisualisationConfiguration;
use ensogl::data::color;
use flo_stream::Subscriber;
Expand Down Expand Up @@ -57,7 +56,7 @@ pub struct ComputedValueInfo {
pub typename: Option<ImString>,
pub payload: ExpressionUpdatePayload,
/// If the expression is a method call (i.e. can be entered), this points to the target method.
pub method_call: Option<SuggestionId>,
pub method_call: Option<MethodPointer>,
}

impl From<ExpressionUpdate> for ComputedValueInfo {
Expand Down Expand Up @@ -120,11 +119,6 @@ impl ComputedValueInfoRegistry {
self.map.borrow().get(id).cloned()
}

/// Look up the registry for method call suggestion ID for given expression.
pub fn get_method_call(&self, id: &ExpressionId) -> Option<SuggestionId> {
self.map.borrow().get(id)?.method_call
}

/// Obtain a `Future` with data from this registry. If data is not available yet, the future
/// will be ready once the data becomes available.
///
Expand Down
20 changes: 10 additions & 10 deletions app/gui/src/presenter/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,7 @@ impl Model {
///
/// If the view update is required, the widget query data is returned.
fn refresh_expression_widgets(&self, expr_id: ast::Id) -> Option<(ast::Id, ast::Id)> {
let suggestion_id = self.expression_method_suggestion(expr_id)?;
let method_pointer = self.suggestion_method_pointer(suggestion_id);
let method_pointer = self.expression_method_pointer(expr_id);
let (_, method_target_id) = self
.state
.update_from_controller()
Expand Down Expand Up @@ -361,17 +360,18 @@ impl Model {
/// Extract the expression's current suggestion entry from controllers.
fn expression_method_suggestion(&self, id: ast::Id) -> Option<SuggestionId> {
let registry = self.controller.computed_value_info_registry();
registry.get(&id)?.method_call
let computed_value = registry.get(&id)?;
let method_pointer = computed_value.method_call.as_ref()?;
let suggestion_db = self.controller.suggestion_db();
suggestion_db.get_method_suggestion(method_pointer)
}

/// Extract the expression's current method pointer from controllers.
fn suggestion_method_pointer(
&self,
method_id: SuggestionId,
) -> Option<view::graph_editor::MethodPointer> {
let suggestion_db = self.controller.suggestion_db();
let method = suggestion_db.lookup_method_ptr(method_id).ok()?;
Some(view::graph_editor::MethodPointer(Rc::new(method)))
fn expression_method_pointer(&self, id: ast::Id) -> Option<view::graph_editor::MethodPointer> {
let registry = self.controller.computed_value_info_registry();
let computed_value = registry.get(&id)?;
let method_pointer = computed_value.method_call.as_ref()?;
Some(view::graph_editor::MethodPointer(Rc::new(method_pointer.clone())))
}

fn file_dropped(&self, file: ensogl_drop_manager::File, position: Vector2<f32>) {
Expand Down
16 changes: 9 additions & 7 deletions app/gui/src/presenter/graph/call_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ impl Model {
debug!("Requesting entering the node {node_id}.");
analytics::remote_log_event("integration::node_entered");
if let Some(call) = self.state.ast_node_id_of_view(node_id) {
match self.controller.node_method_pointer(call) {
Ok(method_pointer) => {
let definition = (*method_pointer).clone();
let local_call = LocalCall { call, definition };
self.enter_expression(local_call);
if let Ok(computed_value) = self.controller.node_computed_value(call) {
if let Some(method_pointer) = computed_value.method_call.as_ref() {
let local_call = LocalCall { call, definition: method_pointer.clone() };
self.enter_expression(local_call)
} else {
info!("Ignoring request to enter non-enterable node {call}.")
}
Err(_) => info!("Ignoring request to enter non-enterable node {call}."),
} else {
info!("Ignoring request to enter not computed node {call}.")
}
} else {
error!("Cannot enter {node_id:?}: no AST node bound to the view.");
error!("Cannot enter {node_id:?}: no AST node bound to the view.")
}
}

Expand Down
Loading