Initial push
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using SqrtSpace.SpaceTime.Analyzers;
|
||||
using Xunit;
|
||||
|
||||
namespace SqrtSpace.SpaceTime.Tests.Analyzers;
|
||||
|
||||
public class LargeAllocationAnalyzerTests : CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
[Fact]
|
||||
public async Task ToList_OnIQueryable_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new TestContext();
|
||||
var result = context.LargeCollection.{|#0:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext
|
||||
{
|
||||
public IQueryable<string> LargeCollection { get; set; }
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("collection"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ToArray_OnLargeCollection_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new DatabaseContext();
|
||||
var array = context.Items.{|#0:ToArray|}();
|
||||
}
|
||||
}
|
||||
|
||||
class DatabaseContext
|
||||
{
|
||||
public IQueryable<Item> Items { get; set; }
|
||||
}
|
||||
|
||||
class Item { }";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("collection"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OrderBy_OnLargeCollection_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new DataContext();
|
||||
var sorted = context.Records.{|#0:OrderBy|}(r => r.Date);
|
||||
}
|
||||
}
|
||||
|
||||
class DataContext
|
||||
{
|
||||
public IQueryable<Record> Records { get; set; }
|
||||
}
|
||||
|
||||
class Record
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("OrderBy"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GroupBy_OnLargeCollection_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new DataContext();
|
||||
var groups = context.Users.{|#0:GroupBy|}(u => u.Country);
|
||||
}
|
||||
}
|
||||
|
||||
class DataContext
|
||||
{
|
||||
public IQueryable<User> Users { get; set; }
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
public string Country { get; set; }
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("GroupBy"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LargeArrayAllocation_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var largeArray = {|#0:new int[100000]|};
|
||||
}
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("array allocation"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LargeListAllocation_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Collections.Generic;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var largeList = {|#0:new List<string>(100000)|};
|
||||
}
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("list allocation"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SmallAllocation_NoDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var smallArray = new int[100];
|
||||
var smallList = new List<string>(100);
|
||||
var items = new[] { 1, 2, 3, 4, 5 };
|
||||
var sorted = items.OrderBy(x => x).ToList();
|
||||
}
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ToList_OnSmallCollection_NoDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var items = new[] { 1, 2, 3, 4, 5 };
|
||||
var list = items.ToList();
|
||||
}
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NestedLinqOperations_ProducesMultipleDiagnostics()
|
||||
{
|
||||
const string source = @"
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new BigDataContext();
|
||||
var result = context.Transactions
|
||||
.{|#0:OrderBy|}(t => t.Date)
|
||||
.{|#1:GroupBy|}(t => t.Category)
|
||||
.{|#2:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class BigDataContext
|
||||
{
|
||||
public IQueryable<Transaction> Transactions { get; set; }
|
||||
}
|
||||
|
||||
class Transaction
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public string Category { get; set; }
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("OrderBy"));
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(1)
|
||||
.WithArguments("GroupBy"));
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(2)
|
||||
.WithArguments("collection"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DynamicSizeAllocation_ProducesDiagnostic()
|
||||
{
|
||||
const string source = @"
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod(int size)
|
||||
{
|
||||
// Dynamic size - analyzer assumes it could be large
|
||||
var array = {|#0:new byte[size]|};
|
||||
}
|
||||
}";
|
||||
|
||||
var test = new CSharpAnalyzerTest<LargeAllocationAnalyzer, XUnitVerifier>
|
||||
{
|
||||
TestCode = source
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.Add(
|
||||
new DiagnosticResult(LargeAllocationAnalyzer.DiagnosticId, DiagnosticSeverity.Warning)
|
||||
.WithLocation(0)
|
||||
.WithArguments("array allocation"));
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using SqrtSpace.SpaceTime.Analyzers;
|
||||
using Xunit;
|
||||
|
||||
namespace SqrtSpace.SpaceTime.Tests.Analyzers;
|
||||
|
||||
public class LargeAllocationCodeFixTests
|
||||
{
|
||||
private static async Task VerifyCodeFixAsync(string source, string fixedSource)
|
||||
{
|
||||
var test = new CSharpCodeFixTest<LargeAllocationAnalyzer, LargeAllocationCodeFixProvider, XUnitVerifier>
|
||||
{
|
||||
TestCode = source,
|
||||
FixedCode = fixedSource,
|
||||
ReferenceAssemblies = ReferenceAssemblies.Net.Net60
|
||||
};
|
||||
|
||||
// Add reference to SpaceTime libraries
|
||||
test.TestState.AdditionalReferences.Add(typeof(SqrtSpace.SpaceTime.Linq.SpaceTimeEnumerable).Assembly);
|
||||
test.TestState.AdditionalReferences.Add(typeof(SqrtSpace.SpaceTime.Collections.AdaptiveList<>).Assembly);
|
||||
|
||||
await test.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ToList_FixesToCheckpointedListAsync()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
async Task TestMethod()
|
||||
{
|
||||
var context = new TestContext();
|
||||
var list = context.LargeCollection.{|ST001:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext
|
||||
{
|
||||
public IQueryable<string> LargeCollection { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
async Task TestMethod()
|
||||
{
|
||||
var context = new TestContext();
|
||||
var list = await context.LargeCollection.ToCheckpointedListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext
|
||||
{
|
||||
public IQueryable<string> LargeCollection { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OrderBy_FixesToOrderByExternal()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new AppContext();
|
||||
var sorted = context.Users.{|ST001:OrderBy|}(u => u.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
class AppContext
|
||||
{
|
||||
public IQueryable<User> Users { get; set; }
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new AppContext();
|
||||
var sorted = context.Users.OrderByExternal(u => u.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
class AppContext
|
||||
{
|
||||
public IQueryable<User> Users { get; set; }
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OrderByDescending_FixesToOrderByDescendingExternal()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new DataContext();
|
||||
var sorted = context.Items.{|ST001:OrderByDescending|}(i => i.Value);
|
||||
}
|
||||
}
|
||||
|
||||
class DataContext
|
||||
{
|
||||
public IQueryable<Item> Items { get; set; }
|
||||
}
|
||||
|
||||
class Item
|
||||
{
|
||||
public int Value { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new DataContext();
|
||||
var sorted = context.Items.OrderByDescendingExternal(i => i.Value);
|
||||
}
|
||||
}
|
||||
|
||||
class DataContext
|
||||
{
|
||||
public IQueryable<Item> Items { get; set; }
|
||||
}
|
||||
|
||||
class Item
|
||||
{
|
||||
public int Value { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GroupBy_FixesToGroupByExternal()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new OrderContext();
|
||||
var grouped = context.Orders.{|ST001:GroupBy|}(o => o.Category);
|
||||
}
|
||||
}
|
||||
|
||||
class OrderContext
|
||||
{
|
||||
public IQueryable<Order> Orders { get; set; }
|
||||
}
|
||||
|
||||
class Order
|
||||
{
|
||||
public string Category { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new OrderContext();
|
||||
var grouped = context.Orders.GroupByExternal(o => o.Category);
|
||||
}
|
||||
}
|
||||
|
||||
class OrderContext
|
||||
{
|
||||
public IQueryable<Order> Orders { get; set; }
|
||||
}
|
||||
|
||||
class Order
|
||||
{
|
||||
public string Category { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LargeList_FixesToAdaptiveList()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Collections.Generic;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var list = {|ST001:new List<string>(100000)|};
|
||||
}
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Collections.Generic;
|
||||
using SqrtSpace.SpaceTime.Collections;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var list = new AdaptiveList<string>();
|
||||
}
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ToList_InNonAsyncMethod_MakesMethodAsync()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
List<string> TestMethod()
|
||||
{
|
||||
var context = new TestContext();
|
||||
return context.LargeCollection.{|ST001:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext
|
||||
{
|
||||
public IQueryable<string> LargeCollection { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
async Task<List<string>> TestMethod()
|
||||
{
|
||||
var context = new TestContext();
|
||||
return await context.LargeCollection.ToCheckpointedListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext
|
||||
{
|
||||
public IQueryable<string> LargeCollection { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComplexLinqChain_FixesMultipleOperations()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new BigDataContext();
|
||||
var result = context.Transactions
|
||||
.Where(t => t.Amount > 100)
|
||||
.{|ST001:OrderBy|}(t => t.Date)
|
||||
.{|ST002:GroupBy|}(t => t.Category)
|
||||
.Select(g => new { Category = g.Key, Count = g.Count() })
|
||||
.{|ST003:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class BigDataContext
|
||||
{
|
||||
public IQueryable<Transaction> Transactions { get; set; }
|
||||
}
|
||||
|
||||
class Transaction
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public string Category { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
}";
|
||||
|
||||
// Note: In practice, multiple code fixes would be applied separately
|
||||
// This test shows the first fix (OrderBy -> OrderByExternal)
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new BigDataContext();
|
||||
var result = context.Transactions
|
||||
.Where(t => t.Amount > 100)
|
||||
.OrderByExternal(t => t.Date)
|
||||
.{|ST002:GroupBy|}(t => t.Category)
|
||||
.Select(g => new { Category = g.Key, Count = g.Count() })
|
||||
.{|ST003:ToList|}();
|
||||
}
|
||||
}
|
||||
|
||||
class BigDataContext
|
||||
{
|
||||
public IQueryable<Transaction> Transactions { get; set; }
|
||||
}
|
||||
|
||||
class Transaction
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public string Category { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PreservesFormatting_AndComments()
|
||||
{
|
||||
const string source = @"
|
||||
using System.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new AppContext();
|
||||
|
||||
// Get all users sorted by name
|
||||
var sorted = context.Users
|
||||
.Where(u => u.IsActive)
|
||||
.{|ST001:OrderBy|}(u => u.Name) // Sort by name
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
class AppContext
|
||||
{
|
||||
public IQueryable<User> Users { get; set; }
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}";
|
||||
|
||||
const string fixedSource = @"
|
||||
using System.Linq;
|
||||
using SqrtSpace.SpaceTime.Linq;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
void TestMethod()
|
||||
{
|
||||
var context = new AppContext();
|
||||
|
||||
// Get all users sorted by name
|
||||
var sorted = context.Users
|
||||
.Where(u => u.IsActive)
|
||||
.OrderByExternal(u => u.Name) // Sort by name
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
class AppContext
|
||||
{
|
||||
public IQueryable<User> Users { get; set; }
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}";
|
||||
|
||||
await VerifyCodeFixAsync(source, fixedSource);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user