using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Amazon.Lambda.Annotations.SourceGenerator
{
public class SemanticModelProvider
{
private readonly GeneratorExecutionContext _context;
public SemanticModelProvider(GeneratorExecutionContext context)
{
_context = context;
}
///
/// Returns the Configure(IServiceCollection) method's semantic model in the LambdaStartup attributed class.
/// If is null, returns null.
///
/// LambdaStartup attributed class syntax
public IMethodSymbol GetConfigureMethodModel(ClassDeclarationSyntax startupSyntax)
{
if (startupSyntax == null)
{
return null;
}
IMethodSymbol configureMethodSymbol = null;
var iServiceCollectionSymbol = _context.Compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.IServiceCollection");
var classModel = _context.Compilation.GetSemanticModel(startupSyntax.SyntaxTree);
// Filter the methods which can potentially have Configure(IServiceCollection) parameter signature
var members = startupSyntax.Members.Where(member => member.Kind() == SyntaxKind.MethodDeclaration);
foreach (var member in members)
{
var methodSyntax = (MethodDeclarationSyntax) member;
var methodSymbol = classModel.GetDeclaredSymbol(methodSyntax);
if (methodSymbol != null
&& methodSymbol.Name == "ConfigureServices"
&& methodSymbol.Parameters.Count() == 1
&& methodSymbol.Parameters[0].Type
.Equals(iServiceCollectionSymbol, SymbolEqualityComparer.Default))
{
configureMethodSymbol = methodSymbol;
break;
}
}
return configureMethodSymbol;
}
///
/// Returns semantic model of
///
/// Method declaration syntax used for representing method by compiler.
public IMethodSymbol GetMethodSemanticModel(MethodDeclarationSyntax syntax)
{
var methodModel = _context.Compilation.GetSemanticModel(syntax.SyntaxTree);
return methodModel.GetDeclaredSymbol(syntax);
}
}
}