Skip to content
Open
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
22 changes: 15 additions & 7 deletions core/src/analyzer/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ use crate::graph::{ChangeSet, VertexId};
use super::bytes_to_name;
use super::parameters::{install_optional_parameter, install_required_parameter, install_rest_parameter};

/// Block processing result
pub(crate) struct BlockResult {
pub param_vtxs: Vec<VertexId>,
pub body_last_vtx: Option<VertexId>,
}

/// Process block node
pub(crate) fn process_block_node(
genv: &mut GlobalEnv,
Expand All @@ -23,14 +29,14 @@ pub(crate) fn process_block_node(
None
}

/// Process block node and return block parameter vertex IDs
/// Process block node and return block parameter vertex IDs and body's last expression vertex
pub(crate) fn process_block_node_with_params(
genv: &mut GlobalEnv,
lenv: &mut LocalEnv,
changes: &mut ChangeSet,
source: &str,
block_node: &ruby_prism::BlockNode,
) -> Vec<VertexId> {
) -> BlockResult {
enter_block_scope(genv);

let mut param_vtxs = Vec::new();
Expand All @@ -42,17 +48,19 @@ pub(crate) fn process_block_node_with_params(
}
}

if let Some(body) = block_node.body() {
let body_last_vtx = if let Some(body) = block_node.body() {
if let Some(statements) = body.as_statements_node() {
super::install::install_statements(genv, lenv, changes, source, &statements);
super::install::install_statements(genv, lenv, changes, source, &statements)
} else {
super::install::install_node(genv, lenv, changes, source, &body);
super::install::install_node(genv, lenv, changes, source, &body)
}
}
} else {
None
};

exit_block_scope(genv);

param_vtxs
BlockResult { param_vtxs, body_last_vtx }
}

/// Install block parameters and return their vertex IDs
Expand Down
40 changes: 27 additions & 13 deletions core/src/analyzer/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::collections::HashMap;

use crate::env::{GlobalEnv, LocalEnv};
use crate::graph::{BlockParameterTypeBox, ChangeSet, VertexId};
use crate::graph::{BlockParameterTypeBox, BlockReturnTypeBox, ChangeSet, VertexId};
use crate::source_map::SourceLocation;
use crate::types::Type;
use ruby_prism::Node;
Expand Down Expand Up @@ -558,34 +558,48 @@ fn process_method_call_common<'a>(
let (positional_arg_vtxs, kwarg_vtxs) =
collect_arguments(genv, lenv, changes, source, arguments.into_iter());

let ret_vtx = finish_method_call(
genv,
recv_vtx,
method_name.clone(),
positional_arg_vtxs,
kwarg_vtxs,
location,
safe_navigation,
);

if let Some(block_node) = block {
if let Some(block) = block_node.as_block_node() {
let param_vtxs = super::blocks::process_block_node_with_params(
let block_result = super::blocks::process_block_node_with_params(
genv, lenv, changes, source, &block,
);

if !param_vtxs.is_empty() {
if !block_result.param_vtxs.is_empty() {
let box_id = genv.alloc_box_id();
let block_box = BlockParameterTypeBox::new(
box_id,
recv_vtx,
method_name.clone(),
param_vtxs,
block_result.param_vtxs,
);
genv.register_box(box_id, Box::new(block_box));
}

if let Some(body_vtx) = block_result.body_last_vtx {
let box_id = genv.alloc_box_id();
let ret_box = BlockReturnTypeBox::new(
box_id,
recv_vtx,
method_name,
body_vtx,
ret_vtx,
);
genv.register_box(box_id, Box::new(ret_box));
}
}
}

Some(finish_method_call(
genv,
recv_vtx,
method_name,
positional_arg_vtxs,
kwarg_vtxs,
location,
safe_navigation,
))
Some(ret_vtx)
}

/// Finish method call after receiver is processed
Expand Down
9 changes: 2 additions & 7 deletions core/src/cache/rbs_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ pub struct SerializableMethodInfo {
pub block_param_types: Option<Vec<String>>,
}

impl SerializableMethodInfo {
/// Parse return type string into Type (simple parser for cached data)
pub fn return_type(&self) -> crate::types::Type {
crate::types::Type::instance(&self.return_type_str)
}
}


impl RbsCache {
/// Get user cache file path (in ~/.cache/methodray/)
Expand Down Expand Up @@ -201,7 +196,7 @@ mod tests {
block_param_types: None,
};

let return_type = method_info.return_type();
let return_type = crate::rbs::converter::RbsTypeConverter::parse(&method_info.return_type_str);
assert_eq!(return_type.show(), "String");
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn load_rbs_from_cache(genv: &mut GlobalEnv) -> Result<()> {
genv.register_builtin_method_with_block(
receiver_type,
&method_info.method_name,
method_info.return_type(),
RbsTypeConverter::parse(&method_info.return_type_str),
block_param_types,
);
}
Expand Down
Loading