dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.05k stars 4.04k forks source link

[VB] Remove redundant `Call` #71818

Closed tats-u closed 6 months ago

tats-u commented 9 months ago

Brief description:

Describe your code style rule here.

VB requires Call before method call expressions if the method calls do not start with identifiers. However, some old-fashioned developers have forced others to add this Call to every method call. It is mainly because of the compatibility with VBA/VB6 and because they do not know when Call is necessary.

Languages applicable:

Is your analyzer C# only? VB Only? Or Both?

VB Only

Code example that the analyzer should report:

Call SomeClass.SomeMethod(arg1, arg2)
'--
'Call' here can be removed.

A small code snippet that describes a case that the analyzer should report.

Note: the following Calls are necessary:

Call New SomeForm().Show()
Call If(condition, form1, form2).Show()

Additional information:

Any more additional information you would like to add.

Documentation requirements:

When this analyzer is implemented, it must be documented by following the steps at Documentation for IDE CodeStyle analyzers.

tats-u commented 9 months ago

https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AbEA3YaAuIAhgM75oAmIA1AD4CSAtgA7T4kAEAygJ5kyMAsACgRAYQylOAMQgQRHRdwCuwDgFkY+ABYQKACgrAMHAIKcAIhFUYYaDhRhgzlpwEtGRDAEoFS/2JeJpo6egBM+r7C/gFBGjAAdCG6FBFRMUqBGME8ElJJWikAzJF+GVkmAEJEUAnVAF6l0RkcFRwAclwAjAmdYXVE9QkAisoITS0cZTHJ4RMtmgWhqfMZ6rmSJCRLxasx1bUNe/6dPX0DQ6Pj6S3TsdkdMADuHAeRI2PHShYeHEQcAF4OAA7Z6vGpfRQ/RgcNRA0EvN43cpxfT/aiw7wfa53TJxNwAM30VhsiXoJHaRHahmM3nsRHswCxVz2AFFgRQVMBplxVPFlmlpuzObzuc1FFxtDUYCK+bMKCVkRxhVyRDAORwwJsSCJxNrwVAeVLYLK1EclSrRTy+SyLRqreKOAAFGxuZyS6WcgDyzBgUCI+Gg1H0JnMBvsUBcsJq3ijwBquMUACUtMooMCOBghRqfX6A9ARCq8ltdcJKYwYCRmEQwDAOt1elwwtN1HplLZwfVE1yOLbu5bVNnOa2KO2YIWNeXK9Xa0A===

var member = callStateMent.Invocation;
while (true)
{
    switch (member)
    {
        case InvocationExpression:
        case SimpleMemberAccessExpression:
            member = member.Expression;
            break;
        case Identifier:
        case MeExpression:
        case MyBaseExpression:
        case MyClassExpression:
        // etc.
            return "Call can be removed";
        default:
            return "Call is mandatory";
    }
}
tats-u commented 6 months ago

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/call-statement#remarks

genlu commented 6 months ago

@tats-u thanks for your feedback and spending time work on a solution. But as mentioned from the discussion in the linked PR, we believe this functionality would be more suitable as a separate analyzer outside of Roslyn.