Skip to content

Commit

Permalink
Further work on making examples
Browse files Browse the repository at this point in the history
  • Loading branch information
glennawatson committed Oct 1, 2020
1 parent 6899fd1 commit 3803bc9
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="stylecop.analyzers" Version="1.2.0-beta.164" PrivateAssets="all" />
<PackageReference Include="stylecop.analyzers" Version="1.2.0-beta.205" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0" PrivateAssets="all" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

using Xamarin.Forms;

[assembly: GenerateStaticEventObservablesAttribute(typeof(StaticTest))]

#pragma warning disable
namespace ReactiveMarbles.ObservableEvents
{
Expand All @@ -24,7 +26,7 @@ public partial class MyForm : Page
/// </summary>
public void Test()
{
var events = this.Events().PropertyChanged.Subscribe();
this.Events().PropertyChanged.Subscribe();
}
}

Expand All @@ -35,4 +37,9 @@ public MyNoEventsClass()
this.Events();
}
}

public static class StaticTest
{
public static event EventHandler? TestChanged;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ public static NullEvents Events<T>(this T eventHost)
}
}
internal static partial class EventsHelper
internal class GenerateStaticEventObservablesAttribute : Attribute
{
public static NullEvents Events<T>()
/// <summary>
/// Initializes a new instance of the <see cref=""GenerateStaticEventObservablesAttribute""/> class.
/// </summary>
/// <param name=""type"">The static type to generate event observable wrappers for.</param>
public GenerateStaticEventObservablesAttribute(Type type)
{
return default(NullEvents);
Type = type;
}
/// <summary>Gets the Type to generate the static event observable wrappers for.
public Type Type { get; }
}
internal struct NullEvents
Expand All @@ -75,6 +82,7 @@ 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 @@ -122,22 +130,16 @@ private static void GenerateEventExtensionMethods(GeneratorExecutionContext cont
out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTypeSymbol NamedType)> staticNamespaceList)
{
var observableGeneratorExtensions = compilation.GetTypeByMetadataName("ReactiveMarbles.ObservableEvents.ObservableGeneratorExtensions");
var staticGeneratorHelper = compilation.GetTypeByMetadataName("ReactiveMarbles.ObservableEvents.EventsHelper");

if (observableGeneratorExtensions == null)
{
throw new InvalidOperationException("Cannot find ReactiveMarbles.ObservableEvents.ObservableGeneratorExtensions");
}

if (staticGeneratorHelper == null)
{
throw new InvalidOperationException("Cannot find ReactiveMarbles.ObservableEvents.EventsHelper");
}

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

foreach (var invocation in receiver.Candidates)
foreach (var invocation in receiver.InstanceCandidates)
{
var semanticModel = compilation.GetSemanticModel(invocation.SyntaxTree);
var methodSymbol = semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
Expand All @@ -147,8 +149,7 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp
continue;
}

if (!SymbolEqualityComparer.Default.Equals(methodSymbol.ContainingType, observableGeneratorExtensions) &&
!SymbolEqualityComparer.Default.Equals(methodSymbol.ContainingType, staticGeneratorHelper))
if (!SymbolEqualityComparer.Default.Equals(methodSymbol.ContainingType, observableGeneratorExtensions))
{
continue;
}
Expand All @@ -168,6 +169,14 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp
var list = callingSymbol.IsStatic ? staticNamespaceList : instanceNamespaceList;
list.Add((invocation, methodSymbol, callingSymbol));
}

Debugger.Launch();
foreach (var attribute in receiver.StaticCandidates)
{
var semanticModel = compilation.GetSemanticModel(attribute.SyntaxTree);

var attributeSymbol = semanticModel.GetSymbolInfo(attribute.ArgumentList.Arguments[0].Expression).Symbol;
}
}

private static bool GenerateEvents(
Expand Down Expand Up @@ -272,18 +281,5 @@ out List<(InvocationExpressionSyntax Invocation, IMethodSymbol Method, INamedTyp
XmlSyntaxFactory.GenerateDocumentationString(
"<auto-generated />"));
}

private class SyntaxReceiver : ISyntaxReceiver
{
public List<InvocationExpressionSyntax> Candidates { get; } = new List<InvocationExpressionSyntax>();

public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is InvocationExpressionSyntax invocation)
{
Candidates.Add(invocation);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2020 ReactiveUI Association Inc. All rights reserved.
// ReactiveUI Association Inc licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace ReactiveMarbles.ObservableEvents.SourceGenerator
{
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);
}
}
}
}
2 changes: 1 addition & 1 deletion src/ReactiveMarbles.ObservableEvents.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30503.244
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveMarbles.ObservableEvents.Test", "ReactiveMarbles.ObservableEvents.Tests\ReactiveMarbles.ObservableEvents.Test.csproj", "{2AF6CBC6-6EE4-4C99-B769-2A777DE6ADFC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveMarbles.ObservableEvents.Example", "ReactiveMarbles.ObservableEvents.Example\ReactiveMarbles.ObservableEvents.Example.csproj", "{2AF6CBC6-6EE4-4C99-B769-2A777DE6ADFC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveMarbles.ObservableEvents.SourceGenerator", "ReactiveMarbles.ObservableEvents.SourceGenerator\ReactiveMarbles.ObservableEvents.SourceGenerator.csproj", "{611C5578-EBDB-4B10-81D1-E7CBEC52D8FB}"
EndProject
Expand Down

0 comments on commit 3803bc9

Please sign in to comment.