vscode-cmantic icon indicating copy to clipboard operation
vscode-cmantic copied to clipboard

Add case statements for enumeration in switch

Open Wastus opened this issue 3 years ago • 2 comments

I'd love to see a feature which generates all cases for a switch statement for all enumeration values.

So if you have:

enum class IicChannel
{
    Iic1,
    Iic2,
    Iic3
};

And write something along the lines of:

IicChannel channel = GetChannel();
switch (channel)
{

}

Have a hint to generate all case statements like:

switch (channel)
{
case IicChannel::Iic1:
    /* code */
    break;
case IicChannel::Iic2:
    /* code */
    break;
case IicChannel::Iic3:
    /* code */
    break;
default:
    break;
}

This would be awesome, I used that feature on ReSharper a lot. Not sure if the parsing you are doing is extensive enough to be able to do this.

Wastus avatar Apr 27 '21 11:04 Wastus

Thank you for the suggestion! I agree, this would be an awesome feature. I think this would fit well into C-mantic's feature set.

Not sure if the parsing you are doing is extensive enough to be able to do this.

Yeah, currently function bodies are treated like "No man's land" - C-mantic doesn't do any parsing there. However, I do have some ideas as to how this could be implemented without much parsing. I don't know if we can realistically recommend this code-action automatically as the user types (the light-bulb). This would probably need to be triggered by the user manually, but that's probably not a big deal.

I do have some questions/concerns as to how this should work though. For instance in your example, it looks like break's and a default would get inserted automatically (is this how it works in ReSharper?). My concern is that you may not always want to break from a case (you may want to return or fall-through). This could probably be configured through a setting or a prompt to insert break for every case, but I feel like simply inserting the case labels might be sufficient, whether the user wants to break, return, or fall-through. In terms of inserting a default, I'm thinking this could be handled by prompting the user to check-box the cases that they want inserted (by default they would all be checked since this is probably the most common case).

Edit: Another concern I have is when the body of the switch is not empty, and we would be adding to existing cases. It might be difficult to determine what cases the user has already defined.

(Here are my ideas on how to implement this, in case someone wants to tackle this issue) After finding the parentheses of the switch statement, we would execute vscode.executeDeclarationProvider on the symbol in the parentheses. This will give us the Location where the symbol is declared (specifically, the location of the symbol's name in its declaration). From there we parse the code preceding the symbol's name to find its type, and we execute vscode.executeDeclarationProvider on the type (auto shouldn't be an issue because cpptools and clangd will provide declarations/definitions for the auto keyword (I'd have to check on ccls)). From there, we get the DocumentSymbol's for the Uri of the type's location, and find the symbol for that type. If it's an enum, we can look at the symbol's children to get all the enumerations.

BigBahss avatar Apr 27 '21 17:04 BigBahss

I think having breaks for each case is more common than the alternatives. Sure, making this configurable is probably the best.

Creating the default is probably not needed, the code snippet provided by the cpptools (I think it comes from there) already has a default, so it's likely already there.

Reshaper has the ability to add missing cases, but that would be a further improvement. Just a "dumb" generator, which creates all cases even if they are already there, would be a great start and help in many cases.

Wastus avatar Apr 29 '21 13:04 Wastus