0
点赞
收藏
分享

微信扫一扫

grafana Not saving new dashboard due to restricted database access

将以下分析器代码编译为DLL后,将DLL添加到项目分析器列表中,即可进行相关分析。

分析器代码

using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace DontCallBaseImplementation
{
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	public class DontCallBaseImplementationAttribute : Attribute { }

	[DiagnosticAnalyzer(LanguageNames.CSharp)]
	public class DontCallBaseImplementationAnalyzer : DiagnosticAnalyzer
	{
		public const string DiagnosticId = "DontCallBaseImplementation";

		private static readonly LocalizableString Title = "Invalid base method implementation call";
		private static readonly LocalizableString MessageFormat = "Method '{0}' with [DontCallBaseImplementationAttribute] should not call base method implementation";
		private static readonly LocalizableString Description = "The method in the derived class calls the base method implementation which is marked with [DontCallBaseImplementationAttribute].";
		private const string Category = "Usage";

		private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category,
			DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);

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

		public override void Initialize(AnalysisContext context)
		{
			context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
			context.EnableConcurrentExecution();
			context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.InvocationExpression);
		}

		private static void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
		{
			InvocationExpressionSyntax invocationExpression = (InvocationExpressionSyntax)context.Node;
			if (invocationExpression.Expression is MemberAccessExpressionSyntax memberAccess &&
				memberAccess.Expression is BaseExpressionSyntax)
			{
				IMethodSymbol invokedSymbol = context.SemanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol;
				if (invokedSymbol == null) return;

				IMethodSymbol currentMethod = context.ContainingSymbol as IMethodSymbol;
				IMethodSymbol baseMethod = currentMethod?.OverriddenMethod;
				if (!SymbolEqualityComparer.Default.Equals(invokedSymbol, baseMethod)) return;

				AttributeData dontCallBaseImplAttr = baseMethod.GetAttributes()
					.FirstOrDefault(attr => attr.AttributeClass.Name == nameof(DontCallBaseImplementationAttribute));
				if (dontCallBaseImplAttr != null)
				{
					Diagnostic diagnostic = Diagnostic.Create(Rule, invocationExpression.GetLocation(), memberAccess.Name);
					context.ReportDiagnostic(diagnostic);
				}
			}
		}
	}
}

添加分析器

在项目的配置文件(csproj)中,添加 ItemGroup 指定分析器引用:

< !--Add to YOUR_PROJECT.csproj-- >
< Project Sdk = "Microsoft.NET.Sdk" >

	< !--... -->

	< ItemGroup >
		< Analyzer Include = "ABSOLUTE_OR_RELATIVE_FOLDER\DontCallBaseImplementation.dll" />
	</ ItemGroup >

	< !--... -->

</ Project >

代码中的使用方法

定义一个 DontCallBaseImplementationAttribute 类(也可以直接使用分析器DLL中提供的同名类,但要为项目添加对DLL的依赖项):

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class DontCallBaseImplementationAttribute : Attribute { }

在不希望子类覆写时调用父类方法实现的虚方法上,添加上述特性:

class BaseClass
{
    [DontCallBaseImplementation]
    public virtual void DoSomething()
    {
        Console.WriteLine("BaseClass.DoSomething()");
    }
}

之后,若子类重写方法时调用了父类方法实现,编辑器会报告错误:

class DerivedClass : BaseClass
{
    public override void DoSomething()
    {
        base.DoSomething(); // Will report an error
    }
}
举报

相关推荐

0 条评论