/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Test/Core/Diagnostics/BoxingOperationAnalyzer.cs
82 строки
4 KB
Tomas Matousek
Move
23 окт 2020, 21:06
23 окт 2020, 21:06
d49cd2b
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.CodeAnalysis.Test.Utilities { /// <summary>Analyzer that looks boxing operations.</summary> public class BoxingOperationAnalyzer : DiagnosticAnalyzer { /// <summary>Diagnostic category "Performance".</summary> private const string PerformanceCategory = "Performance"; private static readonly LocalizableString s_localizableTitle = "Boxing"; private static readonly LocalizableString s_localizableMessage = "Boxing is expensive"; /// <summary>The diagnostic descriptor used when boxing is detected.</summary> public static readonly DiagnosticDescriptor BoxingDescriptor = new DiagnosticDescriptor( "BoxingRule", s_localizableTitle, s_localizableMessage, PerformanceCategory, DiagnosticSeverity.Warning, isEnabledByDefault: true); /// <summary>Gets the set of supported diagnostic descriptors from this analyzer.</summary> public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(BoxingDescriptor); } } public sealed override void Initialize(AnalysisContext context) { context.RegisterOperationAction( (operationContext) => { IOperation operation = operationContext.Operation; if (operation.Kind == OperationKind.Conversion) { IConversionOperation conversion = (IConversionOperation)operation; if (conversion.Type.IsReferenceType && conversion.Operand.Type != null && conversion.Operand.Type.IsValueType && conversion.OperatorMethod == null) { Report(operationContext, conversion.Syntax); } } // Calls to instance methods of value types don’t have conversions. if (operation.Kind == OperationKind.Invocation) { IInvocationOperation invocation = (IInvocationOperation)operation; if (invocation.Instance != null && invocation.Instance.Type.IsValueType && invocation.TargetMethod.ContainingType.IsReferenceType) { Report(operationContext, invocation.Instance.Syntax); } } }, OperationKind.Conversion, OperationKind.Invocation); } /// <summary>Reports a diagnostic warning for a boxing operation.</summary> /// <param name="context">The context.</param> /// <param name="boxingExpression">The expression that produces the boxing.</param> internal void Report(OperationAnalysisContext context, SyntaxNode boxingExpression) { context.ReportDiagnostic(Diagnostic.Create(BoxingDescriptor, boxingExpression.GetLocation())); } } }