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

SyntaxFactory and discards #35558

Open
svick opened this issue May 7, 2019 · 3 comments
Open

SyntaxFactory and discards #35558

svick opened this issue May 7, 2019 · 3 comments
Labels
Area-Compilers Concept-API This issue involves adding, removing, clarification, or modification of an API. Feature Request help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Milestone

Comments

@svick
Copy link
Contributor

svick commented May 7, 2019

Version Used: 3.0.0

Consider the following code:

using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

class Program
{

    static void Main()
    {
        string code = @"
class C
{
    static void Main()
    {
        _ = 0;
    }
}";

        var file = SyntaxFactory.ParseCompilationUnit(code);

        void Compile()
        {
            var tree = SyntaxFactory.SyntaxTree(file);
            var compilation = CSharpCompilation.Create(null)
                .AddSyntaxTrees(tree)
                .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));

            var diagnostics = compilation.GetDiagnostics();

            if (!diagnostics.Any())
                Console.WriteLine("No diagnostics");

            foreach (var diagnostic in diagnostics)
            {
                Console.WriteLine(diagnostic);
            }
        }

        Compile();

        var identifier = file.DescendantNodes().OfType<IdentifierNameSyntax>().Single();
        file = file.ReplaceNode(identifier, SyntaxFactory.IdentifierName("_"));

        Compile();
    }
}

It parses a simple piece of code and compiles it. Then, it replaces the parsed identifier _ with one created using SyntaxFactory.IdentifierName("_") and compiles again.

I would expect both to compile by interpreting the _ as a discard, but they don't; the output of the program above is:

No diagnostics
(6,1): error CS0103: The name '_' does not exist in the current context

As far as I can tell, this happens because the identifier token created by SyntaxFactory does not have its contextual kind set up correctly:

var fromFactory = SyntaxFactory.Identifier("_");
var parsed = ((IdentifierNameSyntax)SyntaxFactory.ParseExpression("_")).Identifier;

SyntaxKind ContextualKind(SyntaxToken token)
{
    var property = typeof(SyntaxToken).GetProperty("RawContextualKind", BindingFlags.NonPublic | BindingFlags.Instance);

    return (SyntaxKind)(int)property.GetValue(token);
}

Console.WriteLine(ContextualKind(fromFactory));
Console.WriteLine(ContextualKind(parsed));

This prints:

IdentifierToken
UnderscoreToken

There is an overload of SyntaxFactory.Identifier which accepts SyntaxKind contextualKind, so it is possible to use SyntaxFactory to create the right identifier token. But shouldn't the simpler overload do this automatically?

@gafter
Copy link
Member

gafter commented Jul 9, 2019

No, we don't parse for you when you are building tokens and nodes. You have to check what the identifier is and set the appropriate contextual kind.

@gafter gafter closed this as completed Jul 9, 2019
@gafter
Copy link
Member

gafter commented Jul 9, 2019

Reopening as a request for an API to determine the contextual kind for a given identifier.

@gafter gafter reopened this Jul 9, 2019
@gafter gafter added Concept-API This issue involves adding, removing, clarification, or modification of an API. Feature Request help wanted The issue is "up for grabs" - add a comment if you are interested in working on it labels Jul 9, 2019
@gafter gafter added this to the Backlog milestone Jul 9, 2019
@CyrusNajmabadi
Copy link
Member

Related issue: #24212

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Concept-API This issue involves adding, removing, clarification, or modification of an API. Feature Request help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Projects
None yet
Development

No branches or pull requests

4 participants