Skip to content

Commit

Permalink
Analyzer allows newing up from within the type itself. Added tests an…
Browse files Browse the repository at this point in the history
…d usages
  • Loading branch information
SteveDunn committed Mar 16, 2023
1 parent 3947e96 commit 9881a80
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 349 deletions.
1 change: 1 addition & 0 deletions Intellenum.sln
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Global
{ACBCBC0B-430F-46A3-AD96-6AF28DBA7F9D}.Release|Any CPU.Build.0 = Release|Any CPU
{89E0B1B1-8CCD-4328-A0D2-4F87E1D57023}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89E0B1B1-8CCD-4328-A0D2-4F87E1D57023}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89E0B1B1-8CCD-4328-A0D2-4F87E1D57023}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38935F7D-8E91-4984-9119-1FB0A639CB09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38935F7D-8E91-4984-9119-1FB0A639CB09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D53F5547-E077-43FF-9342-ABA02A4FF360}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down
30 changes: 30 additions & 0 deletions Scratch/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,39 @@ static Condiment()
}
}

[Intellenum]
[Instance("Salt", 1)]
[Instance("Pepper", 2)]
public partial class CondimentMixedInstances
{
public static readonly CondimentMixedInstances Mayo = new CondimentMixedInstances("Mayo", 5);
public static readonly CondimentMixedInstances Ketchup = new CondimentMixedInstances("Ketchup", 6);

static CondimentMixedInstances()
{
Instance("Vinegar", 3);
Instance("Mustard", 4);
}
}


public class ExplicitInstances
{
[Fact]
public void MixedInstances()
{
CondimentMixedInstances c1 = CondimentMixedInstances.Salt;
CondimentMixedInstances c2 = CondimentMixedInstances.Pepper;

(c1 == c2).Should().BeFalse();

(c1 < c2).Should().BeTrue();

var f1 = CondimentMixedInstances.FromName("Salt");
f1.Should().Be(c1);

}

[Fact]
public void General()
{
Expand Down
16 changes: 15 additions & 1 deletion src/Intellenum/Rules/DoNotUseNewAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Immutable;
using Intellenum.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;

Expand Down Expand Up @@ -43,9 +44,22 @@ private static void AnalyzeExpression(OperationAnalysisContext context)
if (c.Type is not INamedTypeSymbol symbol) return;

if (!VoFilter.IsTarget(symbol)) return;

if (IsContainedWithinIntellenumTypeItself(c)) return;

var diagnostic = DiagnosticsCatalogue.BuildDiagnostic(_rule, symbol.Name, context.Operation.Syntax.GetLocation());

context.ReportDiagnostic(diagnostic);
}

private static bool IsContainedWithinIntellenumTypeItself(IObjectCreationOperation c)
{
SyntaxNode? syntaxNode = c.Syntax;
while (syntaxNode is not null)
{
if (syntaxNode is ClassDeclarationSyntax) break;
syntaxNode = syntaxNode.Parent;
}

return syntaxNode is ClassDeclarationSyntax cds && VoFilter.IsTarget(cds);
}
}
152 changes: 0 additions & 152 deletions tests/AnalyzerTests/AddValidationAnalyzerTests.cs

This file was deleted.

18 changes: 18 additions & 0 deletions tests/AnalyzerTests/AnalyzerTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@
<ProjectReference Include="..\..\src\Intellenum\Intellenum.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Remove="DisallowAbstractTests.cs" />
<Compile Remove="DisallowDuplicateAttributesTests.cs" />
<Compile Remove="DisallowNonPartialTests.cs" />
<Compile Remove="DoNotUseDefaultAnalyzerTests.cs" />
<Compile Remove="DoNotUseConstructorTests.cs" />
<Compile Remove="ToStringOverrrideTests.cs" />
<Compile Remove="GlobalConfig\HappyTests.cs" />
<Compile Remove="GlobalConfig\SadTests.cs" />
<Compile Remove="LocalConfig\HappyTests.cs" />
<Compile Remove="LocalConfig\SadTests.cs" />
</ItemGroup>

<ItemGroup>
<Folder Include="GlobalConfig\" />
<Folder Include="LocalConfig\" />
</ItemGroup>
</Project>


63 changes: 32 additions & 31 deletions tests/AnalyzerTests/DoNotUseNewAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,6 @@ namespace AnalyzerTests
{
public class DoNotUseNewAnalyzerTests
{
private class Types : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new[] {"partial class"};
yield return new[] {"partial struct"};
yield return new[] {"readonly partial struct"};
yield return new[] {"partial record class"};
yield return new[] {"partial record struct"};
yield return new[] {"readonly partial record struct"};
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

//No diagnostics expected to show up
[Fact]
public async Task NoDiagnosticsForEmptyCode()
Expand All @@ -34,15 +19,34 @@ public async Task NoDiagnosticsForEmptyCode()
await VerifyCS.VerifyAnalyzerAsync(test);
}

[Theory]
[ClassData(typeof(Types))]
public async Task Disallow_new_for_creating_value_objects(string type)
[Fact]
public async Task Allow_new_for_newing_up_inside_of_type_itself()
{
var source = @"using Intellenum;
namespace Whatever;
[Intellenum(typeof(int))]
public partial class Condiments
{
// just for the test - it's generated in real life
public Condiments(string name, int value) { }
public static readonly Condiments Salt = new Condiments(""Salt"", 1);
}
";
await Run(
source,
Enumerable.Empty<DiagnosticResult>());
}

[Fact]
public async Task Disallow_new_for_newing_up_outside_of_type_itself()
{
var source = $@"using Intellenum;
namespace Whatever;
[Intellenum(typeof(int))]
public {type} MyVo {{ }}
public partial class MyVo {{ }}
public class Test {{
public Test() {{
Expand All @@ -56,16 +60,15 @@ public class Test {{
WithDiagnostics("VOG010", DiagnosticSeverity.Error, "MyVo", 0, 1));
}

[Theory]
[ClassData(typeof(Types))]
public async Task Disallow_new_for_method_return_type(string type)
[Fact]
public async Task Disallow_new_for_method_return_type()
{
var source = $@"
using Intellenum;
namespace Whatever;
[Intellenum]
public {type} MyVo {{ }}
public partial class MyVo {{ }}
public class Test {{
public MyVo Get() => {{|#0:new MyVo()|}};
Expand All @@ -78,16 +81,15 @@ public class Test {{
WithDiagnostics("VOG010", DiagnosticSeverity.Error, "MyVo", 0, 1));
}

[Theory]
[ClassData(typeof(Types))]
public async Task Disallow_new_from_local_function(string type)
[Fact]
public async Task Disallow_new_from_local_function()
{
var source = $@"
using Intellenum;
namespace Whatever;
[Intellenum]
public {type} MyVo {{ }}
public partial class MyVo {{ }}
public class Test {{
public Test() {{
Expand All @@ -102,9 +104,8 @@ public class Test {{
WithDiagnostics("VOG010", DiagnosticSeverity.Error, "MyVo", 0, 1));
}

[Theory]
[ClassData(typeof(Types))]
public async Task Disallow_new_from_func(string type)
[Fact]
public async Task Disallow_new_from_func()
{
var source = $@"
using System;
Expand All @@ -113,7 +114,7 @@ public async Task Disallow_new_from_func(string type)
namespace Whatever;
[Intellenum]
public {type} MyVo {{ }}
public partial class MyVo {{ }}
public class Test {{
Func<MyVo> f = () => {{|#0:new MyVo()|}};
Expand Down
Empty file.

0 comments on commit 9881a80

Please sign in to comment.