Как получить символьную информацию (или TypeSymbol) ObjectCreationExpressionSyntax через MemberAccessExpressionSyntaxC#

Место общения программистов C#
Ответить
Anonymous
 Как получить символьную информацию (или TypeSymbol) ObjectCreationExpressionSyntax через MemberAccessExpressionSyntax

Сообщение Anonymous »

Я использую Roslyn для анализа инициализации полей. Одной из целей анализа является следующее поле.
private static readonly ImmutableDictionary _Map =
new Dictionary { { 1, 2 }, { 3, 4 }, { 5, 6 } }.ToImmutableDictionary();

Когда это поле анализируется с помощью следующего кода, SemanticModel.GetSymbolInfo работает при вызове метода АнализИнвокация.

Однако он не работает (выдает исключение ArgumentException) при вызове методом АнализОбъектCreation посредством рекурсивного вызова метода АнализВыражение.

I не понимаю, почему это происходит. Как я могу правильно получить символьную информацию (или TypeSymbol) Dictionary (а не ImmutableDictionary)?
мой класс DiagnosticAnalyzer
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeFieldInitialization, SyntaxKind.FieldDeclaration);
}

private static void AnalyzeFieldInitialization(SyntaxNodeAnalysisContext context)
{
if (context.Node is not FieldDeclarationSyntax syntax) return;

var variableSyntax = syntax.Declaration.Variables.FirstOrDefault();
if (variableSyntax is null) return;

var symbol = context.SemanticModel.GetDeclaredSymbol(variableSyntax);
if (symbol == null) return;

// variableSyntax.Initializer?.Value is of type InvocationExpressionSyntax
AnalyzeExpression(context, variableSyntax.Initializer?.Value, symbol.Locations[0], symbol.Name);
}

private static void AnalyzeExpression(
SyntaxNodeAnalysisContext context, ExpressionSyntax expression, Location location, object arg)
{
switch (expression)
{
case ObjectCreationExpressionSyntax objectCreation:
{
AnalyzeObjectCreation(context, objectCreation, location, arg);
return;
}
case InvocationExpressionSyntax invocation:
{
AnalyzeInvocation(context, invocation, location, arg);
return;
}
case MemberAccessExpressionSyntax memberAccess:
{
if (memberAccess.Expression is ObjectCreationExpressionSyntax objectCreation)
{
AnalyzeObjectCreation(context, objectCreation, location, arg);
}
return;
}
}
}

private static void AnalyzeInvocation(
SyntaxNodeAnalysisContext context, InvocationExpressionSyntax expression, Location location, object arg)
{
// GetSymbollnfo works for InvocationExpressionSyntax InvocationExpression
// new Dictionary { { 1, 2 }, { 3, 4 }, { 5, 6 } }.ToImmutableDictionary()

var info = context.SemanticModel.GetSymbolInfo(expression, context.CancellationToken);
if (info.Symbol is not IMethodSymbol method) return;

MyAnalysis(context.Compilation, method.ReturnType);

AnalyzeExpression(context, expression.Expression.WithoutTrivia(), location, arg);
}

private static void AnalyzeObjectCreation(
SyntaxNodeAnalysisContext context, ObjectCreationExpressionSyntax expression, Location location, object arg)
{
// GetSymbolInfo does not work (throws an ArgumentException) for
// expression.Type = GenericNameSyntax GenericName Dictionary

var symbollnfo = context.SemanticModel.GetSymbolInfo(expression.Type, context.CancellationToken);
if (symbollnfo.Symbol is ITypeSymbol typeSymbol)
{
MyAnalysis(context.Compilation, typeSymbol);
}

var initializerExpressions = expression.Initializer?.Expressions.ToArray() ?? Array.Empty();
foreach (var expressionSyntax in initializerExpressions)
{
AnalyzeExpression(context, expressionSyntax, location, arg);
}
}

private static void MyAnalysis(Compilation compilation, ITypeSymbol typeSymbol)
{
// Execute my analysis.
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... syntax-via
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»