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

SyntaxFacts's GetXXXKinds methods can return nonexistent syntax kinds #72300

Closed
DoctorKrolic opened this issue Feb 28, 2024 · 1 comment · Fixed by #72264
Closed

SyntaxFacts's GetXXXKinds methods can return nonexistent syntax kinds #72300

DoctorKrolic opened this issue Feb 28, 2024 · 1 comment · Fixed by #72264

Comments

@DoctorKrolic
Copy link
Contributor

DoctorKrolic commented Feb 28, 2024

Version Used:
Latest main

Steps to Reproduce:
Simple code snippet:

using Microsoft.CodeAnalysis.CSharp;
using System;
using System.Collections.Generic;
using System.Reflection;

foreach (var method in typeof(SyntaxFacts).GetMethods(BindingFlags.Public | BindingFlags.Static))
{
    if (method.ReturnType == typeof(IEnumerable<SyntaxKind>) && method.GetParameters() is [])
    {
        Test(method);
    }
}

static void Test(MethodInfo method)
{
    Console.WriteLine(method.Name);

    foreach (var kind in (IEnumerable<SyntaxKind>)method.Invoke(null, null))
    {
        if (!Enum.IsDefined(kind))
        {
            Console.WriteLine($"Nonexistent kind: {kind}");
        }
    }

    Console.WriteLine();
}

Expected Behavior:
I get no "Nonexistent kind" outputs

Actual Behavior:
The actual output of the program is:

GetReservedKeywordKinds

GetKeywordKinds
Nonexistent kind: 8441

GetPreprocessorKeywordKinds

GetPunctuationKinds
Nonexistent kind: 8223
Nonexistent kind: 8224
Nonexistent kind: 8225
Nonexistent kind: 8226
Nonexistent kind: 8227
Nonexistent kind: 8228
Nonexistent kind: 8229
Nonexistent kind: 8230
Nonexistent kind: 8231
Nonexistent kind: 8240
Nonexistent kind: 8241
Nonexistent kind: 8242
Nonexistent kind: 8243
Nonexistent kind: 8244
Nonexistent kind: 8245
Nonexistent kind: 8246
Nonexistent kind: 8247
Nonexistent kind: 8248
Nonexistent kind: 8249
Nonexistent kind: 8250
Nonexistent kind: 8251
Nonexistent kind: 8252
Nonexistent kind: 8253
Nonexistent kind: 8254
Nonexistent kind: 8255
Nonexistent kind: 8256
Nonexistent kind: 8257
Nonexistent kind: 8258
Nonexistent kind: 8259
Nonexistent kind: 8285

GetContextualKeywordKinds
Nonexistent kind: 8441

As we can see GetKeywordKinds and GetContextualKeywordKinds return single nonexistent kind 8441 and GetPunctuationKinds returns a lot of nonexistent kinds

Additional info:
I think it is pretty safe to assume, that if there is a public API, that has an enum in its return type (single enum value, collection, part of returned object etc.), users of such API expect, that they get valid enum members as a result. I don't expect these APIs to be used often, but when they are used, such nonexistent kinds are most likely a source of potential bug, waiting to happen. E.g. I discovered it while working on an IDE feature fix. For me it was very straight forward to notice, but if this method was used somewhere in more complicated logic, the bug can be left unnoticed for quite a long time

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 28, 2024
@DoctorKrolic
Copy link
Contributor Author

This is not an issue in VB:

using Microsoft.CodeAnalysis.VisualBasic;
using System;
using System.Collections.Generic;
using System.Reflection;

foreach (var method in typeof(SyntaxFacts).GetMethods(BindingFlags.Public | BindingFlags.Static))
{
    if (method.ReturnType == typeof(IEnumerable<SyntaxKind>) && method.GetParameters() is [])
    {
        Test(method);
    }
}

static void Test(MethodInfo method)
{
    Console.WriteLine(method.Name);

    foreach (var kind in (IEnumerable<SyntaxKind>)method.Invoke(null, null))
    {
        if (!Enum.IsDefined(kind))
        {
            Console.WriteLine($"Nonexistent kind: {kind}");
        }
    }

    Console.WriteLine();
}

Output:

GetKeywordKinds

GetReservedKeywordKinds

GetContextualKeywordKinds

GetPunctuationKinds

GetPreprocessorKeywordKinds

@jaredpar jaredpar added Bug and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Mar 12, 2024
@jaredpar jaredpar added this to the Backlog milestone Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants