rib/type_inference/
inferred_expr.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::call_type::CallType;
16use crate::rib_type_error::RibTypeErrorInternal;
17use crate::{
18    ComponentDependencies, CustomInstanceSpec, DynamicParsedFunctionName, Expr, ExprVisitor,
19    FunctionName, GlobalVariableTypeSpec,
20};
21use std::collections::HashSet;
22
23#[derive(Debug, Clone)]
24pub struct InferredExpr(Expr);
25
26impl InferredExpr {
27    pub fn get_expr(&self) -> &Expr {
28        &self.0
29    }
30
31    pub fn from_expr(
32        expr: Expr,
33        component_dependency: &ComponentDependencies,
34        global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
35        custom_instance_spec: &[CustomInstanceSpec],
36    ) -> Result<InferredExpr, RibTypeErrorInternal> {
37        let mut mutable_expr = expr;
38
39        mutable_expr.infer_types(
40            component_dependency,
41            global_variable_type_spec,
42            custom_instance_spec,
43        )?;
44
45        Ok(InferredExpr(mutable_expr))
46    }
47
48    // Only a fully inferred Rib can reliably tell us what are the exact
49    // function calls.
50    pub fn worker_invoke_calls(&self) -> Vec<DynamicParsedFunctionName> {
51        let mut expr = self.0.clone();
52        let mut worker_calls = vec![];
53        let mut visitor = ExprVisitor::bottom_up(&mut expr);
54
55        while let Some(expr) = visitor.pop_back() {
56            if let Expr::Call {
57                call_type: CallType::Function { function_name, .. },
58                ..
59            } = expr
60            {
61                worker_calls.push(function_name.clone());
62            }
63        }
64
65        worker_calls
66    }
67
68    pub fn worker_invoke_registry_keys(&self) -> HashSet<FunctionName> {
69        let worker_calls = self.worker_invoke_calls();
70
71        let mut registry_keys = HashSet::new();
72
73        for call in worker_calls {
74            let keys = FunctionName::from_dynamic_parsed_function_name(&call);
75            registry_keys.insert(keys);
76        }
77
78        registry_keys
79    }
80}