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

[FAQ] How to get object references? (Rust SDK) #397

Open
patrycju opened this issue Jun 25, 2024 · 1 comment
Open

[FAQ] How to get object references? (Rust SDK) #397

patrycju opened this issue Jun 25, 2024 · 1 comment
Labels
faq good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested

Comments

@patrycju
Copy link

How to get object references? (Rust SDK)

Hey! Hope you're doing well! I have a quick questions surrounding Rust SDK.

Let's say I have following KCL file:

schema File:
  name: str
  path: Path

schema Path:
  p: str

ext = "txt"
file_name = "hello.${ext}"
path = Path { p = "/tmp" }

f = File { name = file_name, path = path }

I need to extract references to other identifiers used in any field or value of given object, so for example, based on above file I need to get:

f -> ["file_name", "path"]
file_name -> ["ext"]

Now, I checked Rust SDK and even tried to find it in non-public APIs like Parser or Evaluator, but no luck. I'm slowly learning internals of KCL, but it's very complex and I'm feeling little lost.

Can you please share where can I get this information or at what level should I intercept compilation to get this?

Thank you in advance!

@Peefy
Copy link
Contributor

Peefy commented Jun 26, 2024

Hello @patrycju At present, there is no such advanced APIs in KCL, but code can be written to complete it. The usual way is to use the loader module to obtain the syntax tree and semantic information, which can be obtained from the syntax tree or semantic information. I have written a simple unfinished example list_var_deps as follows

use anyhow::Result;
use std::collections::HashMap;
use kclvm_ast::{ast, walker::MutSelfWalker};
use kclvm_loader::{load_packages, LoadPackageOptions};

#[derive(Debug, Default)]
struct VarDepsExtractor {
    pkgpath: String,
    deps: HashMap<String, Vec<String>>,
    current_var: Option<String>,
}

impl MutSelfWalker for VarDepsExtractor {
    fn walk_identifier(&mut self, identifier: &ast::Identifier) {
        match identifier.ctx {
            ast::ExprContext::Load => todo!(), // Store the deps for the current var
            ast::ExprContext::Store => todo!(),
        }
    }
    fn walk_assign_stmt(&mut self, assign_stmt: &ast::AssignStmt) {
        for target in &assign_stmt.targets {
            self.current_var = target.node.names.first().map(|v|&v.node).cloned();
            self.walk_expr(&assign_stmt.value.node)
        }
    }
}

pub fn list_var_deps(opts: &LoadPackageOptions) -> Result<HashMap<String, Vec<String>>> {
    let packages = load_packages(opts)?;
    let mut extractor = VarDepsExtractor::default();
    for (pkgpath, modules) in &packages.program.pkgs {
        extractor.pkgpath = pkgpath.clone();
        for module in modules {
            extractor.walk_module(module)
        }
    }
    Ok(extractor.deps)
}

Here's another case to get all option functions in the KCL code.

Ref: https://github.com/kcl-lang/kcl/blob/main/kclvm/loader/src/option.rs

@Peefy Peefy added the question Further information is requested label Jun 26, 2024
@Peefy Peefy transferred this issue from kcl-lang/kcl Jun 28, 2024
@Peefy Peefy added help wanted Extra attention is needed faq labels Jun 28, 2024
@Peefy Peefy changed the title How to get object references? (Rust SDK) [FAQ] How to get object references? (Rust SDK) Jun 28, 2024
@Peefy Peefy added the good first issue Good for newcomers label Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
faq good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants