Skip to content

Commit

Permalink
Analyzer for finding index candidates, listing configured indices
Browse files Browse the repository at this point in the history
  • Loading branch information
jokokko committed Aug 3, 2018
1 parent 50d40b3 commit c2c4f2e
Show file tree
Hide file tree
Showing 25 changed files with 651 additions and 72 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

Tool for analyzing codebases using Marten.

This tool is built to supplement [Marten.Analyzers](https://jokokko.github.io/marten.analyzers/) and to aid reviewing codebases using Marten. It makes use of Roslyn code analyzers that maintain some state over solutions and projects.

Available functionality:
- Build a list of configured indices and index candidates
- Display queried properties in query usage frequency
- Build a catalog of projections wired up in provided solution(s)
- Display sites where the projections are wired up
- Categorize projections as synchronous and asynchronous
- Display projections wired as both, synchronous and asynchronous, i.e. projections that can race*

![Screenshot of console - index candidates](assets/consolescreenshot_indices.png)

![Screenshot of console](assets/consolescreenshot.png)

*In such configuration, competing updates can lead to data loss. Synchronous single stream projections can safely be wired in multiple store instances (e.g. in separate processes), as long as versioned methods of the `IEvenStore` are used (see [Marten docs](http://jasperfx.github.io/marten/documentation/events/appending/)).

This tool is built to supplement [Marten.Analyzers](https://jokokko.github.io/marten.analyzers/) and to aid reviewing codebases using Marten. It makes use of Roslyn code analyzer that maintains some state over solutions and projects.

Note: This is a contributor project.
Binary file added assets/consolescreenshot_indices.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ open System
let buildMode = getBuildParamOrDefault "buildMode" "Release"
let buildArtifactPath = FullName "./artifacts"
let packagesPath = FullName "./tools"
let assemblyVersion = "1.1.0.0"
let baseVersion = "1.1.0"
let assemblyVersion = "1.2.0.0"
let baseVersion = "1.2.0"

let envVersion = (environVarOrDefault "APPVEYOR_BUILD_VERSION" (baseVersion + ".0"))
let buildVersion = (envVersion.Substring(0, envVersion.LastIndexOf('.')))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Linq;
using Marten.AnalyzerTool.Analyzers;
using Marten.AnalyzerTool.Tests.Infrastructure;
using Xunit;

namespace Marten.AnalyzerTool.Tests.Analyzers
{
public sealed class IndexCandidateAnalyserTests
{
[Fact]
public async void CanIdentifyIndexCandidates()
{
var analyzer = new IndexCandidateAnalyser();
await TestHelper.GetDiagnosticsAsync(analyzer,
@"using System;
using System.Linq;
using Marten;
using Marten.Schema;
class TestClass
{
void TestMethod()
{
var store = DocumentStore.For(c =>
{
c.Schema.For<Item>().Index(x => x.AnotherMember);
c.Schema.For<Item2>().GinIndexJsonData();
});
var item = new Item();
using (var s = store.OpenSession())
{
s.Query<Item>().Where(x => x.SomeMember == """")
.Where(x => x.ThirdMember == """");
//s.Query<Item>().Where(x => x.Id > 0).First();
//s.Query<Item>().Where(x => x.SomeMember == """" && x.ThirdMember == item.ThirdMember).Where(x => x.SomeMember == ""abc"").First();
//s.Query<Item>().Where(x => x.SomeMember == """").First();
//s.Query<Item>().Where(x => x.SomeMember == """").First();
//s.Query<Item>().Where(x => x.AnotherMember == """").First();
//s.Query<Item>().Where(x => x.AnotherMember == """").First();
//s.Query<Item>().Where(x => x.AnotherMember == """").First();
//s.Query<Item2>().Where(x => x.SomeMember == """").First();
//s.Query<Item2>().Where(x => x.SomeMember == """").First();
//s.Query<Item2>().Where(x => x.SomeMember == """").First();
//s.Query<Item2>().Where(x => x.Identity == 0).First();
}
}
public sealed class Item
{
public int Id { get; set; }
public string SomeMember { get; set; }
public string AnotherMember { get; set; }
public string ThirdMember { get; set; }
}
public sealed class Item2
{
[Identity]
public int Identity { get; set; }
public string SomeMember { get; set; }
}
}");

var indices = analyzer.GetIndices().Select(x => x.ToString()).ToArray();
var candidates = analyzer.GetIndexCandidates().Select(x => x.Property.ToDisplayString()).ToArray();

Assert.Contains("TestClass.Item.AnotherMember", indices);
Assert.Contains("TestClass.Item.SomeMember", candidates);
Assert.DoesNotContain("TestClass.Item.AnotherMember", candidates);
}
}
}
19 changes: 10 additions & 9 deletions src/Marten.AnalyzerTool.Tests/Infrastructure/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Immutable;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Marten.AnalyzerTool.Analyzers;
Expand Down Expand Up @@ -83,16 +84,16 @@ private static async Task<ImmutableArray<Diagnostic>> ApplyAnalyzers(Compilation
private static readonly IEnumerable<MetadataReference> SystemReferences;
static TestHelper()
{
var referencedAssemblies = typeof(TestHelper).Assembly.GetReferencedAssemblies()
.Concat(typeof(ProjectionWiringAnalyser).Assembly.GetReferencedAssemblies())
.Concat(typeof(IDocumentStore).Assembly.GetReferencedAssemblies())
.Concat(new[] { typeof(IsolationLevel).Assembly.GetName(), typeof(object).Assembly.GetName() });

var ignore = new[] {"System","System.Core","System.Transactions","System.Drawing"};

var refs = referencedAssemblies.Where(x => !ignore.Contains(x.Name)).Select(x => (MetadataReference)MetadataReference.CreateFromFile(Assembly.Load(x.Name).Location)).Where(x => x != null);
var refs = new[]
{
MetadataReference.CreateFromFile(typeof(IEnumerable<>).Assembly.Location),
MetadataReference.CreateFromFile(typeof(IQueryable).Assembly.Location),
MetadataReference.CreateFromFile(typeof(IsolationLevel).Assembly.Location),
MetadataReference.CreateFromFile(typeof(IDocumentStore).Assembly.Location),
MetadataReference.CreateFromFile(typeof(IndexCandidateAnalyser).Assembly.Location)
};

SystemReferences = refs;
}
}
}
}
38 changes: 22 additions & 16 deletions src/Marten.AnalyzerTool.Tests/Marten.AnalyzerTool.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,32 +43,34 @@
<HintPath>..\packages\Marten.2.7.1\lib\net46\Marten.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Build.Framework.15.6.82\lib\net46\Microsoft.Build.Framework.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.Build.Framework.15.7.179\lib\net46\Microsoft.Build.Framework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Build.Utilities.Core.15.6.82\lib\net46\Microsoft.Build.Utilities.Core.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.Build.Utilities.Core.15.7.179\lib\net46\Microsoft.Build.Utilities.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.2.7.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath>
<Reference Include="Microsoft.CodeAnalysis, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.2.7.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.7.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
<Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.7.0\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
<Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.8.2\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.7.0\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath>
<Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.8.2\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeCoverage.1.0.3\lib\netstandard1.0\Microsoft.VisualStudio.CodeCoverage.Shim.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Setup.Configuration.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.VisualStudio.Setup.Configuration.Interop.1.16.30\lib\net35\Microsoft.VisualStudio.Setup.Configuration.Interop.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
Expand Down Expand Up @@ -103,6 +105,7 @@
<Reference Include="System.Composition.TypedParts, Version=1.0.31.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.TypedParts.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
</Reference>
Expand Down Expand Up @@ -177,6 +180,7 @@
<Reference Include="System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down Expand Up @@ -210,8 +214,10 @@
<Reference Include="xunit.execution.desktop, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="Analyzers\IndexCandidateAnalyserTests.cs" />
<Compile Include="Analyzers\ProjectionWiringAnalyserTests.cs" />
<Compile Include="Infrastructure\TestHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand All @@ -222,8 +228,8 @@
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.2-beta1\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.2-beta1\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
<Analyzer Include="..\packages\xunit.analyzers.0.7.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/Marten.AnalyzerTool.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
[assembly: AssemblyCopyright("Joona-Pekka Kokko")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]


16 changes: 16 additions & 0 deletions src/Marten.AnalyzerTool.Tests/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@
<assemblyIdentity name="System.Composition.Hosting" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.27.0" newVersion="1.0.27.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.7.0.0" newVersion="2.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.7.0.0" newVersion="2.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis.Workspaces" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.7.0.0" newVersion="2.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis.Workspaces.Desktop" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.7.0.0" newVersion="2.7.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
15 changes: 8 additions & 7 deletions src/Marten.AnalyzerTool.Tests/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
<packages>
<package id="Baseline" version="1.3.0" targetFramework="net462" />
<package id="Marten" version="2.7.1" targetFramework="net462" />
<package id="Microsoft.Build.Framework" version="15.6.82" targetFramework="net462" />
<package id="Microsoft.Build.Utilities.Core" version="15.6.82" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.Common" version="2.7.0" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.CSharp" version="2.7.0" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="2.7.0" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.Workspaces.Common" version="2.7.0" targetFramework="net462" />
<package id="Microsoft.Build.Framework" version="15.7.179" targetFramework="net462" />
<package id="Microsoft.Build.Utilities.Core" version="15.7.179" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.Analyzers" version="2.6.2-beta1" targetFramework="net462" developmentDependency="true" />
<package id="Microsoft.CodeAnalysis.Common" version="2.8.2" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.CSharp" version="2.8.2" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="2.8.2" targetFramework="net462" />
<package id="Microsoft.CodeAnalysis.Workspaces.Common" version="2.8.2" targetFramework="net462" />
<package id="Microsoft.CodeCoverage" version="1.0.3" targetFramework="net462" />
<package id="Microsoft.NET.Test.Sdk" version="15.6.2" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Interop" version="1.16.30" targetFramework="net462" developmentDependency="true" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />
<package id="Npgsql" version="3.2.5" targetFramework="net462" />
<package id="Remotion.Linq" version="2.1.1" targetFramework="net462" />
Expand Down
5 changes: 4 additions & 1 deletion src/Marten.AnalyzerTool.ndproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<NDepend AppName="Marten.AnalyzerTool" Platform="DotNet" FileWrittenByProductVersion="2018.1.0.9030">
<NDepend AppName="Marten.AnalyzerTool" Platform="DotNet" FileWrittenByProductVersion="2018.1.1.9040">
<OutputDir KeepXmlFiles="False">..\artifacts\NDependOut</OutputDir>
<Assemblies>
<Name>Marten.AnalyzerTool</Name>
Expand All @@ -14,6 +14,9 @@
<Name>Microsoft.CodeAnalysis.CSharp</Name>
<Name>System</Name>
<Name>Microsoft.CodeAnalysis.Workspaces.Desktop</Name>
<Name>Colorful.Console</Name>
<Name>HtmlAgilityPack</Name>
<Name>System.Drawing</Name>
</FrameworkAssemblies>
<Dirs>
<Dir>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319</Dir>
Expand Down
Loading

0 comments on commit c2c4f2e

Please sign in to comment.