Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix projects #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/dotnet-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Setup .Net
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Build
run: dotnet build --configuration Release
- name: Test
Expand Down
Empty file.
12 changes: 12 additions & 0 deletions Source/CodeAnalysis/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
DL0001 | Legacy | Error | Analyzer
DL0002 | Style | Error | Analyzer
DL0003 | Openness | Error | Analyzer
DL0004 | Naming | Error | Analyzer
DL0005 | Exceptions | Error | Analyzer
DL0006 | Exceptions | Error | Analyzer
DL0007 | Naming | Error | Analyzer
DL0008 | Exceptions | Error | Analyzer
32 changes: 18 additions & 14 deletions Source/CodeAnalysis/CodeAnalysis.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../default.props"/>
<Import Project="../../default.props" />

<PropertyGroup>
<TargetFramework>net5</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

<AssemblyName>Dolittle.CodeAnalysis</AssemblyName>
<RootNamespace>Dolittle.CodeAnalysis</RootNamespace>
Expand All @@ -14,18 +15,21 @@
<PropertyGroup>
<PackageId>Dolittle.CodeAnalysis</PackageId>
<PackageVersion>1.0.0.0</PackageVersion>
<Authors>einari</Authors>
<PackageProjectUrl>https://github.com/dolittle-tools/DotNET.Common</PackageProjectUrl>
<Authors>Dolittle</Authors>
<PackageProjectUrl>https://github.com/dolittle/DotNET.Common</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>logo.png</PackageIcon>
<RepositoryUrl>https://github.com/dolittle-tools/DotNET.Common</RepositoryUrl>
<RepositoryUrl>https://github.com/dolittle/DotNET.Common</RepositoryUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Description>Dolittle CodeAnalysis Rules</Description>
<Copyright>Copyright</Copyright>
<PackageTags>Dolittle, Code, Analyzers</PackageTags>
<NoPackageAnalysis>true</NoPackageAnalysis>
</PropertyGroup>

<ItemGroup>
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)../../logo.png" Pack="true" Visible="false" PackagePath="" />
<Content Include="../../logo.png" PackagePath="build\" />
Expand All @@ -36,19 +40,19 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.8" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Features" Version="2.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="2.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Features" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="2.2.0" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="4.1.1" PrivateAssets="all" />
<PackageReference Update="NETStandard.Library" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<None Update="tools\*.ps1" CopyToOutputDirectory="Always" Pack="true" PackagePath="" />
<None Update="tools\*.ps1" CopyToOutputDirectory="PreserveNewest" Pack="true" PackagePath="" />
<None Include="$(OutputPath)/$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ public class Analyzer : DiagnosticAnalyzer
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "DL0006",
title: "ExceptionConstructorParametersShouldNotContainMessage",
messageFormat: "An argument of an exception with the name 'message' in it indicates its a generic exception and output string ownership is wrong.",
messageFormat: "An argument of an exception with the name 'message' in it indicates its a generic exception and output string ownership is wrong",
category: "Exceptions",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: null,
helpLinkUri: $"",
helpLinkUri: string.Empty,
customTags: Array.Empty<string>());

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public class Analyzer : DiagnosticAnalyzer
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "DL0007",
title: "ExceptionDescriptionShouldFollowStandard",
messageFormat: $"Exception description for API documentation should start with '{Phrase}'.",
messageFormat: $"Exception description for API documentation should start with '{Phrase}'",
category: "Naming",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: null,
helpLinkUri: $"",
helpLinkUri: string.Empty,
customTags: Array.Empty<string>());

/// <inheritdoc/>
Expand All @@ -50,38 +50,52 @@ public override void Initialize(AnalysisContext context)
SyntaxKind.ClassDeclaration));
}

void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
static void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
{
var classDeclaration = context.Node as ClassDeclarationSyntax;
if (classDeclaration?.BaseList == null || classDeclaration?.BaseList?.Types == null) return;
if (classDeclaration?.BaseList?.Types == null)
{
return;
}

if (classDeclaration.InheritsASystemException(context.SemanticModel))
if (!classDeclaration.InheritsASystemException(context.SemanticModel))
{
foreach (var trivia in classDeclaration.GetLeadingTrivia())
return;
}

foreach (var trivia in classDeclaration.GetLeadingTrivia())
{
if (!trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) && !trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia))
{
if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) ||
trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia))
{
var descendants = trivia.GetStructure().DescendantTokens();
var summaryTokenAndIndex = descendants
.Select((token, index) => new { Token = token, Index = index })
.FirstOrDefault(_ => _.Token.IsKind(SyntaxKind.IdentifierToken) && _.Token.Text.Equals("summary", StringComparison.InvariantCulture));
continue;
}

if (summaryTokenAndIndex == default) return;
var descendants = trivia.GetStructure()?.DescendantTokens().ToArray();
var summaryTokenAndIndex = descendants
.Select((token, index) => new { Token = token, Index = index })
.FirstOrDefault(_ => _.Token.IsKind(SyntaxKind.IdentifierToken) && _.Token.Text.Equals("summary", StringComparison.InvariantCulture));

var xmlTextLiteralToken = descendants
.Skip(summaryTokenAndIndex.Index)
.FirstOrDefault(_ => _.IsKind(SyntaxKind.XmlTextLiteralToken));
if (summaryTokenAndIndex == default)
{
return;
}

var xmlTextLiteralToken = descendants
.Skip(summaryTokenAndIndex.Index)
.FirstOrDefault(_ => _.IsKind(SyntaxKind.XmlTextLiteralToken));

if (xmlTextLiteralToken == default) return;
if (xmlTextLiteralToken == default)
{
return;
}

if (!xmlTextLiteralToken.Text.Trim().StartsWith(Phrase, StringComparison.InvariantCulture))
{
var diagnostic = Diagnostic.Create(Rule, xmlTextLiteralToken.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
if (xmlTextLiteralToken.Text.Trim().StartsWith(Phrase, StringComparison.InvariantCulture))
{
continue;
}

var diagnostic = Diagnostic.Create(Rule, xmlTextLiteralToken.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
Expand Down
33 changes: 18 additions & 15 deletions Source/CodeAnalysis/ExceptionShouldBeSpecific/Analyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public class Analyzer : DiagnosticAnalyzer
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "DL0008",
title: "ExceptionShouldBeSpecific",
messageFormat: "Throwing a generic system exception is not a allowed - you should create a specific exception.",
messageFormat: "Throwing a generic system exception is not a allowed - you should create a specific exception",
category: "Exceptions",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: null,
helpLinkUri: $"",
helpLinkUri: string.Empty,
customTags: Array.Empty<string>());

/// <inheritdoc/>
Expand All @@ -42,23 +42,26 @@ public override void Initialize(AnalysisContext context)
OperationKind.Throw));
}

void HandleThrow(OperationAnalysisContext context)
static void HandleThrow(OperationAnalysisContext context)
{
if (context.Operation is IThrowOperation throwOperation)
if (context.Operation is not IThrowOperation throwOperation)
{
var exceptionOperation = throwOperation.Exception;
if (exceptionOperation is IConversionOperation conversionOperation)
{
exceptionOperation = conversionOperation.Operand;
}
return;
}

var exceptionOperation = throwOperation.Exception;
if (exceptionOperation is IConversionOperation conversionOperation)
{
exceptionOperation = conversionOperation.Operand;
}

if (exceptionOperation is IObjectCreationOperation exception &&
exception.Constructor.ContainingNamespace.Name.StartsWith("System", StringComparison.InvariantCulture))
{
var diagnostic = Diagnostic.Create(Rule, throwOperation.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
}
if (exceptionOperation is not IObjectCreationOperation exception || !exception.Constructor.ContainingNamespace.Name.StartsWith("System", StringComparison.InvariantCulture))
{
return;
}

var diagnostic = Diagnostic.Create(Rule, throwOperation.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
28 changes: 17 additions & 11 deletions Source/CodeAnalysis/ExceptionShouldNotBeSuffixed/Analyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand All @@ -23,12 +22,12 @@ public class Analyzer : DiagnosticAnalyzer
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "DL0004",
title: "ExceptionShouldNotBeSuffixed",
messageFormat: "The use of the word 'Exception' should not be added as a suffix - create a well understood and self explanatory name for the exception.",
messageFormat: "The use of the word 'Exception' should not be added as a suffix - create a well understood and self explanatory name for the exception",
category: "Naming",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: null,
helpLinkUri: $"",
helpLinkUri: string.Empty,
customTags: Array.Empty<string>());

/// <inheritdoc/>
Expand All @@ -45,19 +44,26 @@ public override void Initialize(AnalysisContext context)
SyntaxKind.ClassDeclaration));
}

void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
static void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
{
var classDeclaration = context.Node as ClassDeclarationSyntax;
if (classDeclaration?.BaseList == null || classDeclaration?.BaseList?.Types == null) return;
if (classDeclaration?.BaseList == null || classDeclaration?.BaseList?.Types == null)
{
return;
}

if (!classDeclaration.InheritsASystemException(context.SemanticModel))
{
return;
}

if (classDeclaration.InheritsASystemException(context.SemanticModel))
if (!classDeclaration.Identifier.Text.EndsWith("Exception", StringComparison.InvariantCulture))
{
if (classDeclaration.Identifier.Text.EndsWith("Exception", StringComparison.InvariantCulture))
{
var diagnostic = Diagnostic.Create(Rule, classDeclaration.Identifier.GetLocation());
context.ReportDiagnostic(diagnostic);
}
return;
}

var diagnostic = Diagnostic.Create(Rule, classDeclaration.Identifier.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ public class Analyzer : DiagnosticAnalyzer
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "DL0005",
title: "ExceptionShouldOnlyHaveOneConstructor",
messageFormat: "An exception should not have more than one constructor and typically not a generic one taking a message.",
messageFormat: "An exception should not have more than one constructor and typically not a generic one taking a message",
category: "Exceptions",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: null,
helpLinkUri: $"",
helpLinkUri: string.Empty,
customTags: Array.Empty<string>());

/// <inheritdoc/>
Expand All @@ -45,22 +45,29 @@ public override void Initialize(AnalysisContext context)
SyntaxKind.ClassDeclaration));
}

void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
static void HandleClassDeclaration(SyntaxNodeAnalysisContext context)
{
var classDeclaration = context.Node as ClassDeclarationSyntax;
if (classDeclaration?.BaseList == null || classDeclaration?.BaseList?.Types == null) return;
if (classDeclaration?.BaseList?.Types is null)
{
return;
}

if (!classDeclaration.InheritsASystemException(context.SemanticModel))
{
return;
}

var constructors = classDeclaration.Members.Where(_ => _.IsKind(SyntaxKind.ConstructorDeclaration)).ToArray();
if (constructors.Length <= 1)
{
return;
}

if (classDeclaration.InheritsASystemException(context.SemanticModel))
foreach (var constructor in constructors)
{
var constructors = classDeclaration.Members.Where(_ => _.IsKind(SyntaxKind.ConstructorDeclaration)).ToArray();
if (constructors.Length > 1)
{
foreach (var constructor in constructors)
{
var diagnostic = Diagnostic.Create(Rule, constructor.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
var diagnostic = Diagnostic.Create(Rule, constructor.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
Expand Down
Loading