Skip to content

Commit 2690656

Browse files
authored
VS-88: Set DefaultLinqVersion to V3 in 2.19 and higher. (#32)
1 parent 36545e1 commit 2690656

File tree

13 files changed

+93
-12
lines changed

13 files changed

+93
-12
lines changed

samples/BasicSample/Linq3Sample.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ public void NotSupportedInLinq2Expressions()
2525
var db = mongoClient.GetDatabase("testdb");
2626
var moviesCollection = db.GetCollection<Movie>("movies").AsQueryable();
2727

28-
// Trim() supported in LINQ3 but not in LINQ2 (analyzer provides warning and LINQ3 mql)
28+
// Trim() supported in LINQ3 but not in LINQ2.
29+
// In 2.18 and lower drivers, analyzer provides a warning and LINQ3 mql.
30+
// In 2.19 and higher drivers,LINQ3 MQL is provided without warning.
2931
_ = moviesCollection.Where(m => m.Title.Trim() == "Avatar");
3032

31-
// Substring() supported in LINQ3 but not in LINQ2 (analyzer provides warning and LINQ3 mql)
33+
// Substring() supported in LINQ3 but not in LINQ2.
34+
// In 2.18 and lower drivers, analyzer provides a warning and LINQ3 mql.
35+
// In 2.19 and higher drivers,LINQ3 MQL is provided without warning.
3236
_ = moviesCollection.Where(m => m.Producer.Substring(0, 6) == "Steven");
3337
}
3438
}

samples/BasicSample/mongodb.analyzer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
// Default LINQ provider, for drivers supporting LINQ3 (2.14 and higher)
3-
"DefaultLinqVersion": "V2",
3+
// Default value is V2 in [2.14, 2.18] versions and V3 in [2.19, ) versions
4+
// "DefaultLinqVersion": "V2",
45

56
// Enables builders variables tracking and composition, enabled by default
67
"EnableVariableTracking": true,

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public static CompilationResult Compile(MongoAnalyzerContext context, Expression
4848
}
4949

5050
var isLinq3 = referencesContainer.Version >= LinqAnalysisConstants.MinLinq3Version;
51+
var isLinq3Default = referencesContainer.Version >= LinqAnalysisConstants.DefaultLinq3Version;
5152
var linqProviderSyntaxTree = isLinq3 ? s_linqProviderV3SyntaxTree : s_linqProviderV2SyntaxTree;
53+
var defaultLinqVersion = context.Settings.DefaultLinqVersion ?? (isLinq3Default ? LinqVersion.V3 : LinqVersion.V2);
5254

5355
var typesSyntaxTree = TypesGeneratorHelper.GenerateTypesSyntaxTree(AnalysisType.Linq, linqExpressionAnalysis.TypesDeclarations, s_parseOptions);
5456
var mqlGeneratorSyntaxTree = GenerateMqlGeneratorSyntaxTree(linqExpressionAnalysis, isLinq3);
@@ -80,7 +82,7 @@ public static CompilationResult Compile(MongoAnalyzerContext context, Expression
8082
var mqlGeneratorType = DynamicTypeProvider.GetType(referencesContainer, memoryStream, MqlGeneratorFullName);
8183

8284
linqTestCodeExecutor = mqlGeneratorType != null ?
83-
new LinqMqlGeneratorExecutor(mqlGeneratorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, context.Settings.DefaultLinqVersion) : null;
85+
new LinqMqlGeneratorExecutor(mqlGeneratorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, defaultLinqVersion) : null;
8486
}
8587
else
8688
{

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ namespace MongoDB.Analyzer.Core.Linq;
1717
internal static class LinqAnalysisConstants
1818
{
1919
public const string AnalysisAssemblyName = "DynamicProxyGenAssembly2";
20-
2120
public const string GeneratedTypeName = "GenType";
21+
22+
public static readonly Version DefaultLinq3Version = Version.Parse("2.19");
2223
public static readonly Version MinLinq3Version = Version.Parse("2.14");
2324
}
2425

src/MongoDB.Analyzer/Core/Settings/MongoDBAnalyzerSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal record MongoDBAnalyzerSettings(
3131
[DefaultValue(false)] bool OutputInternalLogsToFile = false,
3232
[DefaultValue(null)] string LogFileName = null,
3333
[DefaultValue(true)] bool SendTelemetry = true,
34-
[DefaultValue(LinqVersion.V2)] LinqVersion DefaultLinqVersion = LinqVersion.V2,
34+
[DefaultValue(null)] LinqVersion? DefaultLinqVersion = null,
3535
[DefaultValue(true)] bool EnableVariableTracking = true)
3636
{
3737
}

src/MongoDB.Analyzer/Core/Telemetry/ITelemetryServiceExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static void AnalysisStarted(
4444
("output_platform", (csharpOptions?.Platform)?.ToString() ?? "Unknown"),
4545
("lang_version", (csharpCompilation?.LanguageVersion)?.ToString() ?? "Unknown"),
4646
("syntax_tree_length", semanticModelAnalysisContext.SemanticModel.SyntaxTree.Length),
47-
("linq_version", settings.DefaultLinqVersion.ToString()),
47+
("linq_version", settings.DefaultLinqVersion?.ToString()),
4848
("logs_enabled", settings.OutputInternalLogsToFile),
4949
("analyzer_version", s_version)
5050
};
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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.Linq;
16+
using MongoDB.Driver.Linq;
17+
18+
namespace MongoDB.Analyzer.Tests.Common.TestCases.Linq
19+
{
20+
public sealed class LinqDefaultVersionInference : TestCasesBase
21+
{
22+
// DriverVersion = (,2.14.0-beta1]
23+
// DefaultLinqProvider = V2
24+
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.V2)]
25+
// DefaultLinqProvider = V3
26+
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.V3)]
27+
// DefaultLinqProvider = Undefined
28+
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.Undefined)]
29+
public void Expression_should_not_be_supported_in_LINQ2_only()
30+
{
31+
_ = GetMongoQueryable()
32+
.Where(u => u.Name.Trim() == "123");
33+
}
34+
35+
// DriverVersion = [2.14.0-beta1, 2.19.0)
36+
// DefaultLinqProvider = V2
37+
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3NonDefault, linqVersion:LinqVersion.V2)]
38+
// DefaultLinqProvider = V3
39+
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3NonDefault, LinqVersion.V3)]
40+
// DefaultLinqProvider = Undefined
41+
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3NonDefault, linqVersion: LinqVersion.Undefined)]
42+
public void Expression_should_be_supported_in_non_default_LINQ3()
43+
{
44+
_ = GetMongoQueryable()
45+
.Where(u => u.Name.Trim() == "123");
46+
}
47+
48+
// DriverVersion = [2.19.0,)
49+
// DefaultLinqProvider = V2
50+
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3DefaultAndHigher)]
51+
// DefaultLinqProvider = V3
52+
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3DefaultAndHigher, LinqVersion.V3)]
53+
// DefaultLinqProvider = Undefined
54+
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3DefaultAndHigher, LinqVersion.Undefined)]
55+
public void Expression_should_be_supported_in_default_LINQ3()
56+
{
57+
_ = GetMongoQueryable()
58+
.Where(u => u.Name.Trim() == "123");
59+
}
60+
}
61+
}

tests/MongoDB.Analyzer.Tests.Common/DiagnosticTestCaseAttribute.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ public sealed class NotSupportedLinq2Attribute : DiagnosticRuleTestCaseAttribute
111111
{
112112
public NotSupportedLinq2Attribute(
113113
string message,
114-
DriverTargetFramework targetFramework = DriverTargetFramework.All) :
115-
base(DiagnosticRulesConstants.NotSupportedLinq2Expression, message, DriverVersions.Linq3AndHigher, LinqVersion.V2, targetFramework)
114+
DriverTargetFramework targetFramework = DriverTargetFramework.All,
115+
string version = DriverVersions.Linq3AndHigher,
116+
LinqVersion linqVersion = LinqVersion.V2) :
117+
base(DiagnosticRulesConstants.NotSupportedLinq2Expression, message, version, linqVersion, targetFramework)
116118
{
117119
}
118120
}

tests/MongoDB.Analyzer.Tests.Common/DriverVersions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public static class DriverVersions
1818
{
1919
public const string Linq3AndHigher = "[2.14.0-beta1,)";
2020
public const string Linq2AndLower = "(,2.14.0-beta1)";
21+
public const string Linq3NonDefault = "[2.14.0-beta1, 2.19.0)";
22+
public const string Linq3DefaultAndHigher = V2_19_AndHigher;
23+
public const string Linq2DefaultAndLower = V2_18_AndLower;
2124
public const string V2_18_AndLower = "(, 2.19.0)";
2225
public const string V2_19_AndHigher = "[2.19.0,)";
2326
}

tests/MongoDB.Analyzer.Tests.Common/LinqVersion.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace MongoDB.Analyzer.Tests.Common
1717
public enum LinqVersion
1818
{
1919
V2,
20-
V3
20+
V3,
21+
Undefined
2122
}
2223
}

tests/MongoDB.Analyzer.Tests/Infrastructure/CodeBasedTestCasesSourceAttribute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ public IEnumerable<object[]> GetData(MethodInfo methodInfo)
4949
public string GetDisplayName(MethodInfo methodInfo, object[] data)
5050
{
5151
var testCase = (DiagnosticTestCase)data[0];
52+
var linqVersion = testCase.LinqVersion == Common.LinqVersion.V3 ? "V3" : testCase.LinqVersion == Common.LinqVersion.Undefined ? "U" : "";
5253

53-
return $"v{testCase.Version}_{(testCase.LinqVersion == Common.LinqVersion.V3 ? "V3" : "")}_{testCase.MethodName}";
54+
return $"v{testCase.Version}_{linqVersion}_{testCase.MethodName}";
5455
}
5556

5657
private DiagnosticTestCase[] CreateTestCases(MemberInfo memberInfo)

tests/MongoDB.Analyzer.Tests/Infrastructure/DiagnosticsAnalyzer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ public static async Task<ImmutableArray<Diagnostic>> Analyze(
5858
compilationOptions);
5959

6060
var mongodbAnalyzer = new MongoDBDiagnosticAnalyzer();
61+
var linqDefaultVersion = linqVersion == Common.LinqVersion.Undefined ? null : (LinqVersion?)linqVersion;
6162

6263
var settings = new MongoDBAnalyzerSettings(
6364
OutputDriverVersion: true,
64-
DefaultLinqVersion: (LinqVersion)linqVersion,
65+
DefaultLinqVersion: linqDefaultVersion,
6566
SendTelemetry: false);
6667
var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create<AdditionalText>(new AdditionalTextAnalyzerSettings(settings)));
6768

tests/MongoDB.Analyzer.Tests/Linq/Linq3Tests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ namespace MongoDB.Analyzer.Tests.Linq;
2222
[TestClass]
2323
public sealed class Linq3Tests : DiagnosticsTestCasesRunner
2424
{
25+
[DataTestMethod]
26+
[CodeBasedTestCasesSource(typeof(LinqDefaultVersionInference))]
27+
public Task LinqDefaultVersionInference(DiagnosticTestCase testCase) => VerifyTestCase(testCase);
28+
2529
[DataTestMethod]
2630
[CodeBasedTestCasesSource(typeof(NotSupportedLinq2))]
2731
public Task NotSupportedLinq2(DiagnosticTestCase testCase) => VerifyTestCase(testCase);

0 commit comments

Comments
 (0)