cairo icon indicating copy to clipboard operation
cairo copied to clipboard

bug: LSP completion dialog should only recommend members of a struct

Open 0xNeshi opened this issue 1 year ago • 13 comments

Bug Report

Cairo version: 2.6.3

Current behavior:

When creating a struct instance, there is no completion dialog support - the one that does appear contains some values that can only be described as random.

Example 1: struct in the same module: image

Example 2: public struct in a different module with a public field: image

Example 3: public struct in a different module with a private field: image

Expected behavior:

Completion dialog for struct instances should only list its available fields and nothing else.

Expected for examples above: Example 1: struct in the same module - should only list field. Example 2: public struct in a different module with a public field - should only list field_2. Example 3: public struct in a different module with a private field - should list nothing.

Steps to reproduce:

  • create a new Scarb package
  • open lib.cairo in VS Code (ensure Cairo 1.0 extension is installed)
  • paste the code from "Related code" section below into the opened file
  • put the cursor inside any of the struct instance creation expressions (between curly brackets)
  • prompt the completion dialog to open (usually CTRL + Space)

Related code:

#[derive(Drop)]
struct Type {
    field: felt252,
}

mod some_mod {
    #[derive(Drop, Debug)]
    pub struct SomeType {
        pub field_2: felt252
    }
}

mod another_mod {
    #[derive(Drop, Debug)]
    pub struct AnotherType {
        field_3: felt252
    }
}

fn main() {
    let struct_instance = Type {
        
    };
    let struct_instance_2 = some_mod::SomeType {
        
    };
    let struct_instance_3 = another_mod::AnotherType {
        
    };
}

Other information:

Related issue: https://github.com/starkware-libs/cairo/issues/5660

0xNeshi avatar May 28 '24 08:05 0xNeshi

Hello @misicnenad, I would like to help with this one if possible!

danielcdz avatar Jun 08 '24 04:06 danielcdz

@danielcdz awesome, please check with @mkaput if he can assign this to you

0xNeshi avatar Jun 08 '24 09:06 0xNeshi

ty @misicnenad, hey @mkaput can I help with this?

danielcdz avatar Jun 08 '24 16:06 danielcdz

@danielcdz yes of course! Task is assigned to you :) Thanks 💖

mkaput avatar Jun 10 '24 07:06 mkaput

Hey @mkaput this is similar to #5660, can I follow the same instructions you left in the comments?

danielcdz avatar Jun 11 '24 03:06 danielcdz

Hey @mkaput this is similar to #5660, can I follow the same instructions you left in the comments?

I think so

mkaput avatar Jun 11 '24 07:06 mkaput

@danielcdz hey, how's it going? Would you like some assistance from my side in this area?

mkaput avatar Jun 17 '24 09:06 mkaput

@mkaput that would be great! I would write some questions below 👇

danielcdz avatar Jun 17 '24 16:06 danielcdz

I'm trying to look where the completions for a struct are being made but I didn't find anything useful, I saw that on issue #5660 you left some comments with examples of where completions are computed, can you help me with something similar for this 🙏

danielcdz avatar Jun 18 '24 02:06 danielcdz

It looks like you have to add a new completion kind for struct fields, here:

https://github.com/starkware-libs/cairo/blob/88f0506651106300e3d05bb3adf9eef0ee77ff24/crates/cairo-lang-language-server/src/ide/completion/mod.rs#L68-L149

This is basically traversing AST up to learn where you are. So you have to check out if you are within braces ({}) of struct construction expression. I guess either the left brace, or comma would be the nodes that you get at the input, but this is an exercise for you to investigate :)

Then, you have to hook completion implementation, starting here add a clause for your new completion kind:

https://github.com/starkware-libs/cairo/blob/88f0506651106300e3d05bb3adf9eef0ee77ff24/crates/cairo-lang-language-server/src/ide/completion/mod.rs#L45-L57

The body of this function is pretty wild west now. You have to get the semantic model of the struct that you are completing. I think you can find a lot of logic to copy in dot completions (i.e. foobar.<complete>), here:

https://github.com/starkware-libs/cairo/blob/57ffe1893a351f587e648e530ba0deb97e853ed8/crates/cairo-lang-language-server/src/ide/completion/completions.rs#L182-L254

For example, this is the function to get struct members (concrete, i.e. with generic parameters resolved to concrete types according to type inference context): https://github.com/starkware-libs/cairo/blob/448c234a612d9012b118f260ca47bcd33425f7d0/crates/cairo-lang-semantic/src/items/structure.rs#L260-L284

mkaput avatar Jun 18 '24 07:06 mkaput

Hey @mkaput ty for all the explanations you gave me, I think I got the main idea on how to solve it, but I prefer to let this issue to a person more experienced in Rust, also I'm participating in a Hackathon and I don't have enough time to solve this issue at the moment, I'm sorry for this 😞

danielcdz avatar Jun 20 '24 04:06 danielcdz

@danielcdz understood :)

I think I got the main idea on how to solve it

Do you think you can add your own two cents to this? This would be a great contribution on its own! 😍

mkaput avatar Jun 20 '24 08:06 mkaput

@KevinMB0220 feel free to submit a PR. We're not assigning tasks to external contributors anymore

mkaput avatar Aug 30 '24 12:08 mkaput