Merge pull request #4 from unoplatform/dev/jela/static-validation
feat: Add UNOM0003 for large static classes validation
This commit is contained in:
Коммит
4294aee15b
12
.vsts-ci.yml
12
.vsts-ci.yml
|
@ -10,17 +10,11 @@ jobs:
|
|||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
inputs:
|
||||
versionSpec: 4.9.1
|
||||
checkLatest: false
|
||||
|
||||
- task: GitVersion@4
|
||||
# Ignore gitversion for forks, until this is fixed:
|
||||
# https://developercommunity.visualstudio.com/content/problem/284991/public-vsts-previouw-cant-set-build-number-of-pr-b.html
|
||||
condition: eq(variables['System.PullRequest.IsFork'], 'False')
|
||||
- task: GitVersion@5
|
||||
inputs:
|
||||
useConfigFile: true
|
||||
configFilePath: gitversion.yml
|
||||
updateAssemblyInfo: false
|
||||
|
||||
- task: DotNetCoreInstaller@0
|
||||
|
|
|
@ -28,3 +28,9 @@ Should become:
|
|||
var s = "";
|
||||
s.TrimStart(new char[0]);
|
||||
```
|
||||
|
||||
## UNOM0003 Large number of static methods in a type with a static initializer
|
||||
|
||||
This analyzer flags type with a static initializer and a large number of static methods.
|
||||
|
||||
Such a pattern can create a very large set of boiler plate code that can be avoided by either removing static type initializers, or move static methods to instance methods and use a singleton.
|
||||
|
|
|
@ -1,21 +1,54 @@
|
|||
assembly-versioning-scheme: MajorMinorPatch
|
||||
mode: ContinuousDeployment
|
||||
next-version: 1.0.0
|
||||
continuous-delivery-fallback-tag: ""
|
||||
mode: Mainline
|
||||
next-version: 1.1
|
||||
|
||||
branches:
|
||||
master:
|
||||
mode: ContinuousDeployment
|
||||
regex: master
|
||||
tag: dev
|
||||
increment: Minor
|
||||
is-source-branch-for: ['beta', 'stable']
|
||||
|
||||
pull-request:
|
||||
regex: ^(pull|pull\-requests|pr)[/-]
|
||||
mode: ContinuousDeployment
|
||||
tag: 'PullRequest'
|
||||
tag-number-pattern: '[/-](?<number>\d+)[-/]'
|
||||
increment: Inherit
|
||||
|
||||
beta:
|
||||
mode: ContinuousDeployment
|
||||
regex: ^release/beta/.*
|
||||
tag: beta
|
||||
increment: none
|
||||
source-branches: ['master']
|
||||
|
||||
stable:
|
||||
tag: ""
|
||||
regex: stable
|
||||
source-branches: ['master']
|
||||
regex: ^release/stable/.*
|
||||
tag: ''
|
||||
increment: Patch
|
||||
source-branches: ['master','beta']
|
||||
is-mainline: true
|
||||
|
||||
dev:
|
||||
mode: ContinuousDeployment
|
||||
regex: ^dev/.*?/(.*?)
|
||||
tag: dev.{BranchName}
|
||||
regex: dev/.*?/(.*?)
|
||||
source-branches: ['master']
|
||||
source-branches: ['master', 'release', 'projects', 'feature']
|
||||
increment: none
|
||||
|
||||
projects:
|
||||
tag: proj-{BranchName}
|
||||
regex: projects/(.*?)
|
||||
regex: ^projects/(.*?)
|
||||
source-branches: ['master']
|
||||
increment: none
|
||||
|
||||
feature:
|
||||
tag: feature.{BranchName}
|
||||
regex: ^feature/(.*?)
|
||||
source-branches: ['master']
|
||||
increment: none
|
||||
|
||||
ignore:
|
||||
sha: []
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
namespace Uno.Analyzers
|
||||
{
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class StaticClassInitializerAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
internal const string Title = "Large number of static methods in a type with a static initializer";
|
||||
internal const string MessageFormat = "{0} has a static type initializer and contains too many static methods. Refactor to use instance methods or remove the static type initializer.";
|
||||
internal const string Description = "This type has a static type initializer and contains too many static methods; this creates a large boiler plate code in every static method";
|
||||
internal const string Category = "Performance";
|
||||
|
||||
internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(
|
||||
"UNOM0003",
|
||||
Title,
|
||||
MessageFormat,
|
||||
Category,
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: Description
|
||||
);
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.EnableConcurrentExecution();
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
|
||||
|
||||
context.RegisterCompilationStartAction(csa =>
|
||||
{
|
||||
var container = new Container(csa.Compilation, this);
|
||||
|
||||
csa.RegisterSymbolAction(c => container.OnSymbolAction(c), SymbolKind.NamedType);
|
||||
});
|
||||
}
|
||||
|
||||
public class Container
|
||||
{
|
||||
private readonly StaticClassInitializerAnalyzer _owner;
|
||||
|
||||
|
||||
public Container(Compilation compilation, StaticClassInitializerAnalyzer owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
internal void OnSymbolAction(SymbolAnalysisContext contextAnalysis)
|
||||
{
|
||||
if(contextAnalysis.Symbol is INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
var hasStaticInitializer = namedTypeSymbol.Constructors.Any(c => c.IsStatic);
|
||||
var staticMethodsCound = namedTypeSymbol
|
||||
.GetMembers()
|
||||
.Count(m => m.Kind == SymbolKind.Method && m.IsStatic);
|
||||
|
||||
if(hasStaticInitializer && staticMethodsCound > 50)
|
||||
{
|
||||
var diagnostic = Diagnostic.Create(
|
||||
_owner.SupportedDiagnostics.First(),
|
||||
namedTypeSymbol.Locations.FirstOrDefault(),
|
||||
namedTypeSymbol.ToDisplayString()
|
||||
);
|
||||
contextAnalysis.ReportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче