Skip to content

Commit

Permalink
Further work on getting the syntax receiver working for static classes
Browse files Browse the repository at this point in the history
  • Loading branch information
glennawatson committed Oct 1, 2020
1 parent 3803bc9 commit 41e1ac7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public static NullEvents Events<T>(this T eventHost)
}
}
/// <summary>
/// Generates a IObservable`T` wrapper for the specified type.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly)]
internal class GenerateStaticEventObservablesAttribute : Attribute
{
/// <summary>
Expand All @@ -59,7 +63,7 @@ public GenerateStaticEventObservablesAttribute(Type type)
Type = type;
}
/// <summary>Gets the Type to generate the static event observable wrappers for.
/// <summary>Gets the Type to generate the static event observable wrappers for.</summary>
public Type Type { get; }
}
Expand All @@ -82,7 +86,6 @@ public void Execute(GeneratorExecutionContext context)
return;
}

////Debugger.Launch();
var compilation = context.Compilation;
var options = (compilation as CSharpCompilation)?.SyntaxTrees[0].Options as CSharpParseOptions;
compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(ExtensionMethodText, Encoding.UTF8), options));
Expand Down Expand Up @@ -126,8 +129,8 @@ private static void GenerateEventExtensionMethods(GeneratorExecutionContext cont
private static void GetAvailableTypes(
Compilation compilation,
SyntaxReceiver receiver,
out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTypeSymbol NamedType)> instanceNamespaceList,
out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTypeSymbol NamedType)> staticNamespaceList)
out List<(Location Location, INamedTypeSymbol NamedType)> instanceNamespaceList,
out List<(Location Location, INamedTypeSymbol NamedType)> staticNamespaceList)
{
var observableGeneratorExtensions = compilation.GetTypeByMetadataName("ReactiveMarbles.ObservableEvents.ObservableGeneratorExtensions");

Expand All @@ -136,8 +139,8 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp
throw new InvalidOperationException("Cannot find ReactiveMarbles.ObservableEvents.ObservableGeneratorExtensions");
}

instanceNamespaceList = new List<(InvocationExpressionSyntax, IMethodSymbol, INamedTypeSymbol)>();
staticNamespaceList = new List<(InvocationExpressionSyntax, IMethodSymbol, INamedTypeSymbol)>();
instanceNamespaceList = new List<(Location Location, INamedTypeSymbol NamedType)>();
staticNamespaceList = new List<(Location Location, INamedTypeSymbol NamedType)>();

foreach (var invocation in receiver.InstanceCandidates)
{
Expand Down Expand Up @@ -166,24 +169,41 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp
continue;
}

var list = callingSymbol.IsStatic ? staticNamespaceList : instanceNamespaceList;
list.Add((invocation, methodSymbol, callingSymbol));
var location = Location.Create(invocation.SyntaxTree, invocation.Span);

instanceNamespaceList.Add((location, callingSymbol));
}

Debugger.Launch();
foreach (var attribute in receiver.StaticCandidates)
foreach (var attribute in compilation.Assembly.GetAttributes())
{
var semanticModel = compilation.GetSemanticModel(attribute.SyntaxTree);
if (attribute.AttributeClass.Name != "GenerateStaticEventObservablesAttribute")
{
continue;
}

if (attribute.ConstructorArguments.Length == 0)
{
continue;
}

var type = attribute.ConstructorArguments[0].Value as INamedTypeSymbol;

if (type == null)
{
continue;
}

var location = Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span);

var attributeSymbol = semanticModel.GetSymbolInfo(attribute.ArgumentList.Arguments[0].Expression).Symbol;
staticNamespaceList.Add((location, type));
}
}

private static bool GenerateEvents(
GeneratorExecutionContext context,
IEventSymbolGenerator symbolGenerator,
bool isStatic,
IReadOnlyList<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTypeSymbol NamedType)> symbols,
IReadOnlyList<(Location Location, INamedTypeSymbol NamedType)> symbols,
List<MethodDeclarationSyntax>? methodInvocationExtensions = null)
{
var processedItems = new HashSet<INamedTypeSymbol>(TypeDefinitionNameComparer.Default);
Expand Down Expand Up @@ -246,8 +266,7 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp

if (!hasEvents)
{
var location = Location.Create(symbol.Invocation.SyntaxTree, symbol.Invocation.Span);
context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("PHARM001", "Events not found", $"Could not find events on '{symbol.Method.ToDisplayString(RoslynHelpers.SymbolDisplayFormat)}' or its base classes.", "ObservableEventsGenerator", DiagnosticSeverity.Warning, true), location));
context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("PHARM001", "Events not found", $"Could not find events on '{symbol.NamedType.ToDisplayString(RoslynHelpers.SymbolDisplayFormat)}' or its base classes.", "ObservableEventsGenerator", DiagnosticSeverity.Warning, true), symbol.Location));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,12 @@ internal class SyntaxReceiver : ISyntaxReceiver
{
public List<InvocationExpressionSyntax> InstanceCandidates { get; } = new List<InvocationExpressionSyntax>();

public List<AttributeSyntax> StaticCandidates { get; } = new List<AttributeSyntax>();

public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is InvocationExpressionSyntax invocation)
{
InstanceCandidates.Add(invocation);
}

if (syntaxNode is AttributeSyntax attribute && attribute.Name.ToFullString() == "GenerateStaticEventObservablesAttribute")
{
StaticCandidates.Add(attribute);
}
}
}
}

0 comments on commit 41e1ac7

Please sign in to comment.