Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions samples/BasicSample/Linq3Sample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ public void NotSupportedInLinq2Expressions()
var db = mongoClient.GetDatabase("testdb");
var moviesCollection = db.GetCollection<Movie>("movies").AsQueryable();

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

// Substring() supported in LINQ3 but not in LINQ2 (analyzer provides warning and LINQ3 mql)
// Substring() supported in LINQ3 but not in LINQ2.
// In 2.18 and lower drivers, analyzer provides a warning and LINQ3 mql.
// In 2.19 and higher drivers,LINQ3 MQL is provided without warning.
_ = moviesCollection.Where(m => m.Producer.Substring(0, 6) == "Steven");
}
}
Expand Down
3 changes: 2 additions & 1 deletion samples/BasicSample/mongodb.analyzer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
// Default LINQ provider, for drivers supporting LINQ3 (2.14 and higher)
"DefaultLinqVersion": "V2",
// Default value is V2 in [2.14, 2.18] versions and V3 in [2.19, ) versions
// "DefaultLinqVersion": "V2",

// Enables builders variables tracking and composition, enabled by default
"EnableVariableTracking": true,
Expand Down
4 changes: 3 additions & 1 deletion src/MongoDB.Analyzer/Core/Linq/AnalysisCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public static CompilationResult Compile(MongoAnalyzerContext context, Expression
}

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

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

linqTestCodeExecutor = mqlGeneratorType != null ?
new LinqMqlGeneratorExecutor(mqlGeneratorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, context.Settings.DefaultLinqVersion) : null;
new LinqMqlGeneratorExecutor(mqlGeneratorType, isLinq3 ? LinqVersion.V3 : LinqVersion.V2, defaultLinqVersion) : null;
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion src/MongoDB.Analyzer/Core/Linq/LinqAnalysisConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ namespace MongoDB.Analyzer.Core.Linq;
internal static class LinqAnalysisConstants
{
public const string AnalysisAssemblyName = "DynamicProxyGenAssembly2";

public const string GeneratedTypeName = "GenType";

public static readonly Version DefaultLinq3Version = Version.Parse("2.19");
public static readonly Version MinLinq3Version = Version.Parse("2.14");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal record MongoDBAnalyzerSettings(
[DefaultValue(false)] bool OutputInternalLogsToFile = false,
[DefaultValue(null)] string LogFileName = null,
[DefaultValue(true)] bool SendTelemetry = true,
[DefaultValue(LinqVersion.V2)] LinqVersion DefaultLinqVersion = LinqVersion.V2,
[DefaultValue(null)] LinqVersion? DefaultLinqVersion = null,
[DefaultValue(true)] bool EnableVariableTracking = true)
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static void AnalysisStarted(
("output_platform", (csharpOptions?.Platform)?.ToString() ?? "Unknown"),
("lang_version", (csharpCompilation?.LanguageVersion)?.ToString() ?? "Unknown"),
("syntax_tree_length", semanticModelAnalysisContext.SemanticModel.SyntaxTree.Length),
("linq_version", settings.DefaultLinqVersion.ToString()),
("linq_version", settings.DefaultLinqVersion?.ToString()),
("logs_enabled", settings.OutputInternalLogsToFile),
("analyzer_version", s_version)
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2021-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Linq;
using MongoDB.Driver.Linq;

namespace MongoDB.Analyzer.Tests.Common.TestCases.Linq
{
public sealed class LinqDefaultVersionInference : TestCasesBase
{
// DriverVersion = (,2.14.0-beta1]
// DefaultLinqProvider = V2
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.V2)]
// DefaultLinqProvider = V3
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.V3)]
// DefaultLinqProvider = Undefined
[InvalidLinq("{document}{Name}.Trim() is not supported.", DriverVersions.Linq2AndLower, LinqVersion.Undefined)]
public void Expression_should_not_be_supported_in_LINQ2_only()
{
_ = GetMongoQueryable()
.Where(u => u.Name.Trim() == "123");
}

// DriverVersion = [2.14.0-beta1, 2.19.0)
// DefaultLinqProvider = V2
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3NonDefault, linqVersion:LinqVersion.V2)]
// DefaultLinqProvider = V3
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3NonDefault, LinqVersion.V3)]
// DefaultLinqProvider = Undefined
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3NonDefault, linqVersion: LinqVersion.Undefined)]
public void Expression_should_be_supported_in_non_default_LINQ3()
{
_ = GetMongoQueryable()
.Where(u => u.Name.Trim() == "123");
}

// DriverVersion = [2.19.0,)
// DefaultLinqProvider = V2
[NotSupportedLinq2("Supported in LINQ3 only: db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", version: DriverVersions.Linq3DefaultAndHigher)]
// DefaultLinqProvider = V3
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3DefaultAndHigher, LinqVersion.V3)]
// DefaultLinqProvider = Undefined
[MQL("db.coll.Aggregate([{ \"$match\" : { \"Name\" : /^\\s*(?!\\s)123(?<!\\s)\\s*$/s } }])", DriverVersions.Linq3DefaultAndHigher, LinqVersion.Undefined)]
public void Expression_should_be_supported_in_default_LINQ3()
{
_ = GetMongoQueryable()
.Where(u => u.Name.Trim() == "123");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ public sealed class NotSupportedLinq2Attribute : DiagnosticRuleTestCaseAttribute
{
public NotSupportedLinq2Attribute(
string message,
DriverTargetFramework targetFramework = DriverTargetFramework.All) :
base(DiagnosticRulesConstants.NotSupportedLinq2Expression, message, DriverVersions.Linq3AndHigher, LinqVersion.V2, targetFramework)
DriverTargetFramework targetFramework = DriverTargetFramework.All,
string version = DriverVersions.Linq3AndHigher,
LinqVersion linqVersion = LinqVersion.V2) :
base(DiagnosticRulesConstants.NotSupportedLinq2Expression, message, version, linqVersion, targetFramework)
{
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/MongoDB.Analyzer.Tests.Common/DriverVersions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public static class DriverVersions
{
public const string Linq3AndHigher = "[2.14.0-beta1,)";
public const string Linq2AndLower = "(,2.14.0-beta1)";
public const string Linq3NonDefault = "[2.14.0-beta1, 2.19.0)";
public const string Linq3DefaultAndHigher = V2_19_AndHigher;
public const string Linq2DefaultAndLower = V2_18_AndLower;
public const string V2_18_AndLower = "(, 2.19.0)";
public const string V2_19_AndHigher = "[2.19.0,)";
}
Expand Down
3 changes: 2 additions & 1 deletion tests/MongoDB.Analyzer.Tests.Common/LinqVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace MongoDB.Analyzer.Tests.Common
public enum LinqVersion
{
V2,
V3
V3,
Undefined
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public IEnumerable<object[]> GetData(MethodInfo methodInfo)
public string GetDisplayName(MethodInfo methodInfo, object[] data)
{
var testCase = (DiagnosticTestCase)data[0];
var linqVersion = testCase.LinqVersion == Common.LinqVersion.V3 ? "V3" : testCase.LinqVersion == Common.LinqVersion.Undefined ? "U" : "";

return $"v{testCase.Version}_{(testCase.LinqVersion == Common.LinqVersion.V3 ? "V3" : "")}_{testCase.MethodName}";
return $"v{testCase.Version}_{linqVersion}_{testCase.MethodName}";
}

private DiagnosticTestCase[] CreateTestCases(MemberInfo memberInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ public static async Task<ImmutableArray<Diagnostic>> Analyze(
compilationOptions);

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

var settings = new MongoDBAnalyzerSettings(
OutputDriverVersion: true,
DefaultLinqVersion: (LinqVersion)linqVersion,
DefaultLinqVersion: linqDefaultVersion,
SendTelemetry: false);
var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create<AdditionalText>(new AdditionalTextAnalyzerSettings(settings)));

Expand Down
4 changes: 4 additions & 0 deletions tests/MongoDB.Analyzer.Tests/Linq/Linq3Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ namespace MongoDB.Analyzer.Tests.Linq;
[TestClass]
public sealed class Linq3Tests : DiagnosticsTestCasesRunner
{
[DataTestMethod]
[CodeBasedTestCasesSource(typeof(LinqDefaultVersionInference))]
public Task LinqDefaultVersionInference(DiagnosticTestCase testCase) => VerifyTestCase(testCase);

[DataTestMethod]
[CodeBasedTestCasesSource(typeof(NotSupportedLinq2))]
public Task NotSupportedLinq2(DiagnosticTestCase testCase) => VerifyTestCase(testCase);
Expand Down