Skip to content

Commit 2f8db4e

Browse files
VS-63 : POCO to Json Analyzer (#41)
1 parent 994bc50 commit 2f8db4e

File tree

56 files changed

+2112
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2112
-121
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2021-present MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License")
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using MongoDB.Bson;
17+
using MongoDB.Bson.Serialization.Options;
18+
using MongoDB.Driver;
19+
20+
namespace MongoDB.Analyzer.Helpers.Poco
21+
{
22+
public static class JsonGenerator
23+
{
24+
#pragma warning disable CS0169 // These fields are never used, they are needed to ensure that the relevant usings are not accidently removed
25+
#pragma warning disable IDE0051
26+
private static readonly BsonType s_dummyRef1;
27+
private static readonly TimeSpanUnits s_dummyRef2;
28+
#pragma warning restore IDE0051 // These fields are never used, they are needed to ensure that the relevant usings are not accidently removed
29+
#pragma warning restore CS0169
30+
31+
public static string GetDriverVersion() => typeof(JsonFilterDefinition<>).Assembly.GetName().Version.ToString(3);
32+
33+
public static string GetJson(Action<object> populatePoco)
34+
{
35+
var poco = new object();
36+
populatePoco(poco);
37+
return poco.ToJson();
38+
}
39+
}
40+
}
41+

src/MongoDB.Analyzer/Core/Builders/AnalysisCodeGenerator.cs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using static MongoDB.Analyzer.Core.HelperResources.MqlGeneratorSyntaxElements.Builders;
15+
using MongoDB.Analyzer.Core.Utilities;
1616
using static MongoDB.Analyzer.Core.HelperResources.ResourcesUtilities;
1717

1818
namespace MongoDB.Analyzer.Core.Builders;
@@ -57,35 +57,15 @@ public static CompilationResult Compile(MongoAnalysisContext context, Expression
5757
syntaxTrees.Add(s_renderer_2_19_and_higher);
5858
}
5959

60-
var compilation = CSharpCompilation.Create(
61-
BuildersAnalysisConstants.AnalysisAssemblyName,
62-
syntaxTrees,
63-
referencesContainer.References,
64-
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
65-
66-
using var memoryStream = new MemoryStream();
67-
var emitResult = compilation.Emit(memoryStream);
68-
69-
BuildersMqlGeneratorExecutor buildersMqlCodeExecutor = null;
70-
71-
if (emitResult.Success)
60+
var generatorType = AnalysisCodeGeneratorUtilities.CompileAndGetGeneratorType(AnalysisType.Builders, context, referencesContainer, syntaxTrees);
61+
if (generatorType == null)
7262
{
73-
context.Logger.Log("Compilation successful");
74-
75-
memoryStream.Seek(0, SeekOrigin.Begin);
76-
77-
var mqlGeneratorType = DynamicTypeProvider.GetType(referencesContainer, memoryStream, MqlGeneratorFullName);
78-
79-
buildersMqlCodeExecutor = mqlGeneratorType != null ? new BuildersMqlGeneratorExecutor(mqlGeneratorType) : null;
80-
}
81-
else
82-
{
83-
context.Logger.Log($"Compilation failed with: {string.Join(Environment.NewLine, emitResult.Diagnostics)}");
63+
return CompilationResult.Failure;
8464
}
8565

8666
var result = new CompilationResult(
87-
buildersMqlCodeExecutor != null,
88-
buildersMqlCodeExecutor,
67+
true,
68+
new BuildersMqlGeneratorExecutor(generatorType),
8969
referencesContainer.Version);
9070

9171
return result;

src/MongoDB.Analyzer/Core/Builders/BuildersAnalysisConstants.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,5 @@ namespace MongoDB.Analyzer.Core.Builders;
1616

1717
internal static class BuildersAnalysisConstants
1818
{
19-
public const string AnalysisAssemblyName = "DynamicProxyGenAssembly2";
20-
2119
public static readonly Version Version_2_19_and_higher = Version.Parse("2.19.0");
2220
}

src/MongoDB.Analyzer/Core/Builders/BuildersAnalyzer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static bool AnalyzeBuilders(MongoAnalysisContext context)
3333
stats = ReportMqlOrInvalidExpressions(context, buildersAnalysis);
3434

3535
sw.Stop();
36-
context.Logger.Log($"Builders analysis ended: with {stats.MqlCount} mql translations, {stats.DriverExceptionsCount} unsupported expressions, {stats.InternalExceptionsCount} internal exceptions in {sw.ElapsedMilliseconds}.");
36+
context.Logger.Log($"Builders analysis ended: with {stats.MqlCount} mql translations, {stats.DriverExceptionsCount} unsupported expressions, {stats.InternalExceptionsCount} internal exceptions in {sw.ElapsedMilliseconds}ms.");
3737
}
3838
catch (Exception ex)
3939
{
@@ -104,7 +104,7 @@ private static AnalysisStats ReportMqlOrInvalidExpressions(MongoAnalysisContext
104104
}
105105
}
106106

107-
return new AnalysisStats(mqlCount, internalExceptionsCount, driverExceptionsCount, compilationResult.MongoDBDriverVersion.ToString(3), null);
107+
return new AnalysisStats(mqlCount, 0, internalExceptionsCount, driverExceptionsCount, compilationResult.MongoDBDriverVersion.ToString(3), null);
108108
}
109109

110110
private static bool IsDriverOrBsonException(MQLResult mqlResult)

src/MongoDB.Analyzer/Core/Builders/BuildersMqlGeneratorTemplateBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
using static MongoDB.Analyzer.Core.HelperResources.MqlGeneratorSyntaxElements.Builders;
16+
1617
namespace MongoDB.Analyzer.Core.Builders;
1718

1819
internal sealed class BuildersMqlGeneratorTemplateBuilder
@@ -28,7 +29,6 @@ internal record SyntaxElements(
2829
}
2930

3031
private readonly SyntaxElements _syntaxElements;
31-
3232
private ClassDeclarationSyntax _mqlGeneratorDeclarationSyntaxNew;
3333
private int _nextTestMethodIndex;
3434

src/MongoDB.Analyzer/Core/ExpressionAnalysis.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ internal enum AnalysisType
1818
{
1919
Unknown,
2020
Builders,
21-
Linq
21+
Linq,
22+
Poco
2223
}
2324

2425
internal sealed class ExpressionsAnalysis
@@ -49,10 +50,11 @@ internal record InvalidExpressionAnalysisNode(SyntaxNode OriginalExpression, par
4950

5051
internal record AnalysisStats(
5152
int MqlCount,
53+
int JsonCount,
5254
int InternalExceptionsCount,
5355
int DriverExceptionsCount,
5456
string DriverVersion,
5557
string TargetFramework)
5658
{
57-
public static AnalysisStats Empty { get; } = new AnalysisStats(0, 0, 0, null, null);
58-
}
59+
public static AnalysisStats Empty { get; } = new AnalysisStats(0, 0, 0, 0, null, null);
60+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2021-present MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License")
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace MongoDB.Analyzer.Core.HelperResources;
16+
17+
internal static class JsonSyntaxElements
18+
{
19+
internal static class Poco
20+
{
21+
public const string GetDriverVersion = nameof(GetDriverVersion);
22+
public const string JsonGenerator = nameof(JsonGenerator);
23+
public const string JsonGeneratorFullName = JsonGeneratorNamespace + "." + JsonGenerator;
24+
public const string JsonGeneratorMainMethodName = "GetJson";
25+
public const string JsonGeneratorNamespace = "MongoDB.Analyzer.Helpers.Poco";
26+
public const string JsonGeneratorTemplateType = nameof(JsonGeneratorTemplateType);
27+
}
28+
}

src/MongoDB.Analyzer/Core/HelperResources/ResourceNames.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ internal static class Builders
3333
public const string Renderer_2_19_and_higher = $"Builders.{nameof(Renderer_2_19_and_higher)}";
3434
}
3535

36+
internal static class Poco
37+
{
38+
public const string JsonGenerator = $"Poco.{nameof(JsonGenerator)}";
39+
}
40+
3641
public const string EmptyCursor = nameof(EmptyCursor);
3742
public const string MongoClientMock = nameof(MongoClientMock);
3843
public const string MongoCollectionMock = nameof(MongoCollectionMock);

src/MongoDB.Analyzer/Core/Linq/AnalysisCodeGenerator.cs

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using static MongoDB.Analyzer.Core.HelperResources.MqlGeneratorSyntaxElements.Linq;
15+
using MongoDB.Analyzer.Core.Utilities;
1616
using static MongoDB.Analyzer.Core.HelperResources.ResourcesUtilities;
1717

1818
namespace MongoDB.Analyzer.Core.Linq;
@@ -49,9 +49,9 @@ public static CompilationResult Compile(MongoAnalysisContext context, Expression
4949

5050
var isLinq3 = referencesContainer.Version >= LinqAnalysisConstants.MinLinq3Version;
5151
var isLinq3Default = referencesContainer.Version >= LinqAnalysisConstants.DefaultLinq3Version;
52-
var linqProviderSyntaxTree = isLinq3 ? s_linqProviderV3SyntaxTree : s_linqProviderV2SyntaxTree;
5352
var defaultLinqVersion = context.Settings.DefaultLinqVersion ?? (isLinq3Default ? LinqVersion.V3 : LinqVersion.V2);
5453

54+
var linqProviderSyntaxTree = isLinq3 ? s_linqProviderV3SyntaxTree : s_linqProviderV2SyntaxTree;
5555
var typesSyntaxTree = TypesGeneratorHelper.GenerateTypesSyntaxTree(AnalysisType.Linq, linqExpressionAnalysis.TypesDeclarations, s_parseOptions);
5656
var mqlGeneratorSyntaxTree = GenerateMqlGeneratorSyntaxTree(linqExpressionAnalysis, isLinq3);
5757

@@ -62,36 +62,15 @@ public static CompilationResult Compile(MongoAnalysisContext context, Expression
6262
mqlGeneratorSyntaxTree
6363
};
6464

65-
var compilation = CSharpCompilation.Create(
66-
LinqAnalysisConstants.AnalysisAssemblyName,
67-
syntaxTrees,
68-
referencesContainer.References,
69-
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
70-
71-
using var memoryStream = new MemoryStream();
72-
var emitResult = compilation.Emit(memoryStream);
73-
74-
LinqMqlGeneratorExecutor linqTestCodeExecutor = null;
75-
76-
if (emitResult.Success)
65+
var generatorType = AnalysisCodeGeneratorUtilities.CompileAndGetGeneratorType(AnalysisType.Linq, context, referencesContainer, syntaxTrees);
66+
if (generatorType == null)
7767
{
78-
context.Logger.Log("Compilation successful");
79-
80-
memoryStream.Seek(0, SeekOrigin.Begin);
81-
82-
var mqlGeneratorType = DynamicTypeProvider.GetType(referencesContainer, memoryStream, MqlGeneratorFullName);
83-
84-
linqTestCodeExecutor = mqlGeneratorType != null ?
85-
new LinqMqlGeneratorExecutor(mqlGeneratorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, defaultLinqVersion) : null;
86-
}
87-
else
88-
{
89-
context.Logger.Log($"Compilation failed with: {string.Join(Environment.NewLine, emitResult.Diagnostics)}");
68+
return CompilationResult.Failure;
9069
}
9170

9271
var result = new CompilationResult(
93-
linqTestCodeExecutor != null,
94-
linqTestCodeExecutor,
72+
true,
73+
new LinqMqlGeneratorExecutor(generatorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, defaultLinqVersion),
9574
referencesContainer.Version);
9675

9776
return result;

src/MongoDB.Analyzer/Core/Linq/LinqAnalysisConstants.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ namespace MongoDB.Analyzer.Core.Linq;
1616

1717
internal static class LinqAnalysisConstants
1818
{
19-
public const string AnalysisAssemblyName = "DynamicProxyGenAssembly2";
2019
public const string GeneratedTypeName = "GenType";
21-
2220
public static readonly Version DefaultLinq3Version = Version.Parse("2.19");
2321
public static readonly Version MinLinq3Version = Version.Parse("2.14");
2422
}

0 commit comments

Comments
 (0)