0

I'm trying to write Code Analyzer in .NET for a custom query language that evaluates string literals that are being assigned to a type called OGraphStringQuery. I then try to identify if there are any syntax errors which then reports a diagnostic error.

Currently Roslyn does not support embedded language syntax and even though they've exposed StringSyntaxAttribute in .NET 7 it requires the use of these interfaces that are currently internal to Roslyn.

My strategy is to identify String Literals and back-peddle to get the type being assigned. I'm not sure what the best strategy is but here is the route I am taking though I am not sure how to back-peddle for the type in which OGraphStringQuery is being assigned.

Is the current path I'm taking the correct

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class OGraphStringQueryAnalyzer : DiagnosticAnalyzer
{

    public const string DiagnosticId = "APN0001";

    private static readonly LocalizableString Title = default!;
    private static readonly LocalizableString MessageFormat = default!;
    private static readonly LocalizableString Description = default!;
    private static readonly DiagnosticDescriptor Rule = default!;


    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
    public override void Initialize(AnalysisContext context)
    {
        context.EnableConcurrentExecution();
        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
        context.RegisterSemanticModelAction(static context =>
        {
            var model       = context.SemanticModel;
            var tree        = model.SyntaxTree;
            var root        = tree.GetRoot();
            var descendants = root.DescendantNodes();

            foreach (var literal in descendants.OfType<LiteralExpressionSyntax>())
            {
                if (literal.IsKind(SyntaxKind.StringLiteralExpression))
                {
                    // Get the raw String Value
                    var value = literal.Token.ValueText;


                    if (literal.Parent is EqualsValueClauseSyntax equal)
                    {
                        if (equal.Parent is VariableDeclaratorSyntax declarator && declarator.Parent is VariableDeclarationSyntax declaration)
                        {

                            var item = model.GetSymbolInfo(declaration);
                        }
                    }

                    context.ReportDiagnostic(Diagnostic.Create(
                        Rule,
                        literal.GetLocation(),
                        value));
                }
            }
        });
    }
}


// For reference here is what the OGraphQuerString would look like
// FYI: logic removed to reduce verbosity
public readonly struct OGraphStringQuery
{
    public OGraphStringQuery(sting query)
    {
    }

    public static implicit operator OGraphStringQuery(string query) => new OGraphStringQuery(query);

}


What I would like to happen.

public class Program
{
   public void Main(string[] args)
   {
       OGraphStringQuery query = "some query string";
       //                               ^
       //                               |
       //           Analyzers spits out error for string only for 
       //              OGraphStringQuery type being assinged
   }

}

0 Answers0