Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/SemanticModelProvider.cs (67 lines of code) (raw):
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;
}
/// <summary>
/// Returns the Configure(IServiceCollection) method's semantic model in the LambdaStartup attributed class.
/// If <see cref="startupSyntax"/> is null, returns null.
/// </summary>
/// <param name="startupSyntax">LambdaStartup attributed class syntax</param>
public IMethodSymbol GetConfigureServicesMethodModel(ClassDeclarationSyntax startupSyntax)
{
if (startupSyntax == null)
{
return null;
}
IMethodSymbol configureServicesMethodSymbol = 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))
{
configureServicesMethodSymbol = methodSymbol;
break;
}
}
return configureServicesMethodSymbol;
}
public IMethodSymbol GetConfigureHostBuilderMethodModel(ClassDeclarationSyntax startupSyntax)
{
if (startupSyntax == null)
{
return null;
}
IMethodSymbol configureHostBuilderMethodSymbol = null;
var classModel = _context.Compilation.GetSemanticModel(startupSyntax.SyntaxTree);
foreach (var member in startupSyntax.Members.Where(member => member.Kind() == SyntaxKind.MethodDeclaration))
{
var methodSyntax = (MethodDeclarationSyntax)member;
var methodSymbol = classModel.GetDeclaredSymbol(methodSyntax);
if (methodSymbol != null && methodSymbol.Name == "ConfigureHostBuilder")
{
configureHostBuilderMethodSymbol = methodSymbol;
break;
}
}
return configureHostBuilderMethodSymbol;
}
/// <summary>
/// Returns semantic model of <see cref="syntax"/>
/// </summary>
/// <param name="syntax">Method declaration syntax used for representing method by compiler.</param>
public IMethodSymbol GetMethodSemanticModel(MethodDeclarationSyntax syntax)
{
var methodModel = _context.Compilation.GetSemanticModel(syntax.SyntaxTree);
return methodModel.GetDeclaredSymbol(syntax);
}
}
}