diff --git a/src/ReactiveMarbles.ObservableEvents.SourceGenerator/EventGeneratorHook.cs b/src/ReactiveMarbles.ObservableEvents.SourceGenerator/EventGeneratorHook.cs index 76b18e4..a73ff32 100644 --- a/src/ReactiveMarbles.ObservableEvents.SourceGenerator/EventGeneratorHook.cs +++ b/src/ReactiveMarbles.ObservableEvents.SourceGenerator/EventGeneratorHook.cs @@ -48,6 +48,10 @@ public static NullEvents Events(this T eventHost) } } + /// + /// Generates a IObservable`T` wrapper for the specified type. + /// + [AttributeUsage(AttributeTargets.Assembly)] internal class GenerateStaticEventObservablesAttribute : Attribute { /// @@ -59,7 +63,7 @@ public GenerateStaticEventObservablesAttribute(Type type) Type = type; } - /// Gets the Type to generate the static event observable wrappers for. + /// Gets the Type to generate the static event observable wrappers for. public Type Type { get; } } @@ -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)); @@ -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"); @@ -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) { @@ -166,16 +169,33 @@ 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)); } } @@ -183,7 +203,7 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp GeneratorExecutionContext context, IEventSymbolGenerator symbolGenerator, bool isStatic, - IReadOnlyList<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTypeSymbol NamedType)> symbols, + IReadOnlyList<(Location Location, INamedTypeSymbol NamedType)> symbols, List? methodInvocationExtensions = null) { var processedItems = new HashSet(TypeDefinitionNameComparer.Default); @@ -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)); } } diff --git a/src/ReactiveMarbles.ObservableEvents.SourceGenerator/SyntaxReceiver.cs b/src/ReactiveMarbles.ObservableEvents.SourceGenerator/SyntaxReceiver.cs index 417deca..de7ef6a 100644 --- a/src/ReactiveMarbles.ObservableEvents.SourceGenerator/SyntaxReceiver.cs +++ b/src/ReactiveMarbles.ObservableEvents.SourceGenerator/SyntaxReceiver.cs @@ -17,19 +17,12 @@ internal class SyntaxReceiver : ISyntaxReceiver { public List InstanceCandidates { get; } = new List(); - public List StaticCandidates { get; } = new List(); - 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); - } } } }