Skip to content

Commit

Permalink
some small refactoring (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
protomorphine authored Sep 16, 2024
1 parent 4cf0fa0 commit d63450e
Show file tree
Hide file tree
Showing 29 changed files with 202 additions and 143 deletions.
9 changes: 9 additions & 0 deletions .omnisharp/omnisharp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"RoslynExtensionsOptions": {
"enableImportCompletion": true,
"enableAnalyzersSupport": true,
"locationPaths": [
"../src/ImmutableAnalyzer/ImmutableAnalyzer/bin/Release/netstandard2.0/publish/ImmutableAnalyzer.dll"
]
}
}
26 changes: 26 additions & 0 deletions src/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/ImmutableAnalyzer/ImmutableAnalyzer.Tests/bin/Debug/net6.0/ImmutableAnalyzer.Tests.dll",
"args": [],
"cwd": "${workspaceFolder}/ImmutableAnalyzer/ImmutableAnalyzer.Tests",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
41 changes: 41 additions & 0 deletions src/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/ImmutableAnalyzer.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/ImmutableAnalyzer.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/ImmutableAnalyzer.sln"
],
"problemMatcher": "$msCompile"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;

namespace ImmutableAnalyzer.Tests.Factories;
Expand Down Expand Up @@ -114,4 +114,4 @@ private static (int Line, int Column) GetLineAndColumn(string source, string tex

return (line + 1, column + 1);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using ImmutableAnalyzer.PropertyAnalyzers.SetAccessor;
using ImmutableAnalyzer.Tests.Factories;
using Xunit;
Expand Down Expand Up @@ -44,4 +44,4 @@ public async Task Immutable_class_property_could_have_no_setter()
var source = SourceFactory.ImmutableClassWithGetOnlyPropertyAccessor();
await Verifier.VerifyAnalyzerAsync(source);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
using Microsoft.CodeAnalysis.Testing;
using Xunit;
using FixStrategy = ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorCodeFixProvider.FixStrategy;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.CodeFixVerifier<
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorAnalyzer,
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorCodeFixProvider
>;
using SetAccessorCodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest<
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorAnalyzer,
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorCodeFixProvider,
Microsoft.CodeAnalysis.Testing.Verifiers.XUnitVerifier
>;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.CodeFixVerifier<
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorAnalyzer,
ImmutableAnalyzer.PropertyAnalyzers.SetAccessor.SetAccessorCodeFixProvider
>;

namespace ImmutableAnalyzer.Tests.PropertyAnalyzersTests.SetAccessorTests;

Expand Down Expand Up @@ -60,10 +60,10 @@ private static SetAccessorCodeFixTest CreateTest(FixStrategy fixStrategy)

var fixedSource = fixStrategy switch
{
FixStrategy.Remove => SourceFactory.ImmutableClassWithGetOnlyPropertyAccessor(),
FixStrategy.ToInit => SourceFactory.ImmutableClassWithPropertyAccessor("init", out _, out _),
FixStrategy.Remove => SourceFactory.ImmutableClassWithGetOnlyPropertyAccessor(),
FixStrategy.ToInit => SourceFactory.ImmutableClassWithPropertyAccessor("init", out _, out _),
FixStrategy.ToPrivate => SourceFactory.ImmutableClassWithPropertyAccessor("private set", out _, out _),
_ => throw new ArgumentOutOfRangeException(nameof(fixStrategy), fixStrategy, null)
_ => throw new ArgumentOutOfRangeException(nameof(fixStrategy), fixStrategy, null)
};

return new SetAccessorCodeFixTest
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using ImmutableAnalyzer.ParameterAnalyzers;
using ImmutableAnalyzer.Tests.Factories;
using Xunit;
Expand Down Expand Up @@ -31,4 +31,4 @@ public async Task Record_with_mutable_property_should_not_be_immutable(string pr
var expected = Verifier.Diagnostic().WithLocation(line, column).WithArguments(property);
await Verifier.VerifyAnalyzerAsync(source, expected);
}
}
}
10 changes: 5 additions & 5 deletions src/ImmutableAnalyzer/ImmutableAnalyzer.Tests/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Xunit;
using TypeCheckerConst = ImmutableAnalyzer.Utils.TypeChecking.Const.TypeCheckerConst;
using Types = ImmutableAnalyzer.Utils.TypeChecking.Const.Types;

namespace ImmutableAnalyzer.Tests;

Expand All @@ -13,26 +13,26 @@ public static class TestData
{
/// <summary>
/// Represent immutable built-in types.
/// <seealso cref="TypeCheckerConst.ImmutableTypes"/>
/// <seealso cref="Types.ImmutableTypes"/>
/// </summary>
public class ImmutableTypes : TheoryData<string>
{
public ImmutableTypes()
{
foreach (var typeName in TypeCheckerConst.ImmutableTypes)
foreach (var typeName in Types.ImmutableTypes)
Add(typeName);
}
}

/// <summary>
/// Represent immutable built-in generic types.
/// <seealso cref="TypeCheckerConst.ImmutableGenericTypes"/>
/// <seealso cref="Types.Generic"/>
/// </summary>
public class ImmutableGenericsTypes : TheoryData<string>
{
public ImmutableGenericsTypes()
{
foreach (var typeName in TypeCheckerConst.ImmutableGenericTypes)
foreach (var typeName in Types.Generic)
Add(CreateGenericTypeStringWithParams(typeName, nameof(Int32)));
}

Expand Down
4 changes: 2 additions & 2 deletions src/ImmutableAnalyzer/ImmutableAnalyzer/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("ImmutableAnalyzer.Tests")]
[assembly: InternalsVisibleTo("ImmutableAnalyzer.Tests")]
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace ImmutableAnalyzer.Abstractions;
namespace ImmutableAnalyzer.Common;

/// <summary>
/// Base class for member analyzers in immutable class.
/// <typeparam name="TMemberSyntax">Type of class member to analyze.</typeparam>
/// </summary>
internal abstract class MemberAnalyzer<TMemberSyntax> : TypeDeclarationAnalyzer<TypeDeclarationSyntax>
internal abstract class MemberAnalyzer<TMemberSyntax>
: TypeDeclarationAnalyzer<TypeDeclarationSyntax>
{
/// <summary>
/// Execute analyzer.
Expand All @@ -18,8 +19,7 @@ internal abstract class MemberAnalyzer<TMemberSyntax> : TypeDeclarationAnalyzer<

/// <summary>
/// Execute analyzer.
/// Executes <see cref="AnalyzeMember"/> only if class declaration
/// marked by <see cref="ImmutableAttribute"/>.
/// Executes <see cref="AnalyzeMember"/> only if class declaration marked by <see cref="ImmutableAttribute"/>.
/// </summary>
/// <param name="typeDeclaration">Type declaration node.</param>
/// <param name="ctx">Analysis context.</param>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace ImmutableAnalyzer.Abstractions;
namespace ImmutableAnalyzer.Common;

/// <summary>
/// Base class for parameter analyzer in immutable records.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using ImmutableAnalyzer.Extensions;
using ImmutableAnalyzer.Extensions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace ImmutableAnalyzer.Abstractions;
namespace ImmutableAnalyzer.Common;

/// <summary>
/// Base class for type declaration analyzer.
Expand Down Expand Up @@ -40,7 +40,9 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
if (context.ContainingSymbol is { } symbol && !symbol.HasAttribute<ImmutableAttribute>())
return;

if (context.Node is TDeclarationSyntax typeDeclarationSyntax)
AnalyzeTypeDeclaration(typeDeclarationSyntax, context);
if (context.Node is not TDeclarationSyntax typeDeclarationSyntax)
return;

AnalyzeTypeDeclaration(typeDeclarationSyntax, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ namespace ImmutableAnalyzer.Extensions;
internal static class SymbolExtensions
{
/// <summary>
/// Checks if <see cref="symbol"/> marked by given attribute.
/// Checks if <paramref name="symbol"/> marked by given attribute.
/// </summary>
/// <param name="symbol">Symbol, exposed by compiler.</param>
/// <returns>true - if symbol marked by given attribute, otherwise - false.</returns>
/// <returns>true - if <paramref name="symbol"/> marked by given attribute, otherwise - false.</returns>
public static bool HasAttribute<T>(this ISymbol symbol) =>
symbol.GetAttributes().Any(data => data.AttributeClass?.Name == typeof(T).Name);

/// <summary>
/// Returns symbol from type and context.
/// Returns symbol from type.
/// </summary>
/// <param name="type">Type syntax expression.</param>
/// <param name="semanticModel">Semantic model.</param>
Expand All @@ -30,8 +30,8 @@ public static ITypeSymbol GetTypeSymbolFromSyntaxNode(this SemanticModel semanti
return symbol switch
{
IArrayTypeSymbol arrayTypeSymbol => arrayTypeSymbol.ElementType, // detect arrays e.g. int[] -> int
not null => symbol, // just return type symbol
_ => throw new NotSupportedException("Not supported symbol")
not null => symbol, // just return type symbol
_ => throw new NotSupportedException("Not supported symbol")
};
}
}
4 changes: 2 additions & 2 deletions src/ImmutableAnalyzer/ImmutableAnalyzer/ImmutableAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System;

namespace ImmutableAnalyzer;

/// <summary>
/// Attribute, that represent immutable class.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
public class ImmutableAttribute : Attribute { }
public class ImmutableAttribute : Attribute { }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Collections.Immutable;
using ImmutableAnalyzer.Abstractions;
using ImmutableAnalyzer.Common;
using ImmutableAnalyzer.Extensions;
using ImmutableAnalyzer.Utils.TypeChecking;
using Microsoft.CodeAnalysis;
Expand All @@ -20,20 +20,22 @@ internal class ParameterTypeAnalyzer : ParameterAnalyzer
private static readonly TypeChecker Checker = TypeCheckerFactory.GetOrCreate();

/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } =
ImmutableArray.Create(Rule);

/// <summary>
/// Diagnostic descriptor.
/// </summary>
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "IM0003",
title: "Mutable parameter in record parameter list",
messageFormat: "Immutable record can't have parameter of type '{0}'",
category: "Design",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Record parameter must have immutable type."
);
private static readonly DiagnosticDescriptor Rule =
new(
id: "IM0003",
title: "Mutable parameter in record parameter list",
messageFormat: "Immutable record can't have parameter of type '{0}'",
category: "Design",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Record parameter must have immutable type."
);

/// <inheritdoc />
protected override void AnalyzeParameter(ParameterSyntax node, SyntaxNodeAnalysisContext ctx)
Expand All @@ -42,7 +44,8 @@ protected override void AnalyzeParameter(ParameterSyntax node, SyntaxNodeAnalysi
return;

var diagnostic = Diagnostic.Create(
Rule, node.Type!.GetLocation(),
Rule,
node.Type!.GetLocation(),
node.Type.ToFullString().Trim()
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using ImmutableAnalyzer.Abstractions;
using ImmutableAnalyzer.Common;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace ImmutableAnalyzer.PropertyAnalyzers;

/// <summary>
/// Base class for property analyzer in immutable type.
/// </summary>
internal abstract class PropertyAnalyzer : MemberAnalyzer<PropertyDeclarationSyntax> { }
internal abstract class PropertyAnalyzer : MemberAnalyzer<PropertyDeclarationSyntax> { }
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Immutable;
using System.Collections.Immutable;
using ImmutableAnalyzer.Extensions;
using ImmutableAnalyzer.Utils.TypeChecking;
using Microsoft.CodeAnalysis;
Expand All @@ -24,14 +24,14 @@ internal sealed class PropertyTypeAnalyzer : PropertyAnalyzer
/// <summary>
/// Diagnostic descriptor.
/// </summary>
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "IM0001",
title: "Mutable property in immutable type",
messageFormat: "Immutable type can't have property of type '{0}'",
category: "Design",
defaultSeverity: DiagnosticSeverity.Error,
private static readonly DiagnosticDescriptor Rule = new(
id: "IM0001",
title: "Mutable property in immutable type",
messageFormat: "Immutable type can't have property of type '{0}'",
category: "Design",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Class member must have immutable type."
description: "Class member must have immutable type."
);

/// <inheritdoc/>
Expand Down
Loading

0 comments on commit d63450e

Please sign in to comment.