| File: CallAnalysis\StartsEndsWith.cs | Web Access |
| Project: src\src\Analyzers\Microsoft.Analyzers.Extra\Microsoft.Analyzers.Extra.csproj (Microsoft.Analyzers.Extra) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.Extensions.ExtraAnalyzers.CallAnalysis; /// <summary> /// Recommends char (instead of string) versions of String.StartsWith and String.EndsWith when possible. /// </summary> internal sealed class StartsEndsWith { public StartsEndsWith(CallAnalyzer.Registrar reg) { var stringType = reg.Compilation.GetSpecialType(SpecialType.System_String); var stringCompType = reg.Compilation.GetTypeByMetadataName("System.StringComparison"); var startsWith = stringType.GetMembers("StartsWith").OfType<IMethodSymbol>() .Where(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, stringType)) .Where(m => (m.Parameters.Length == 1) || (m.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(m.Parameters[1].Type, stringCompType))); var endsWith = stringType.GetMembers("EndsWith").OfType<IMethodSymbol>() .Where(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, stringType)) .Where(m => (m.Parameters.Length == 1) || (m.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(m.Parameters[1].Type, stringCompType))); foreach (var m in startsWith) { reg.RegisterMethod(m, Handle); } foreach (var m in endsWith) { reg.RegisterMethod(m, Handle); } static void Handle(OperationAnalysisContext context, IInvocationOperation op) { var s = op.Arguments[0].Value.ConstantValue.Value as string; if (s != null && s.Length == 1) { if (op.Arguments.Length > 1 && op.Arguments[1].Value.ConstantValue.HasValue) { var comp = (StringComparison)op.Arguments[1].Value.ConstantValue.Value!; if (comp != StringComparison.Ordinal) { return; } } var diagnostic = Diagnostic.Create(DiagDescriptors.StartsEndsWith, op.Syntax.GetLocation(), op.TargetMethod.Name); context.ReportDiagnostic(diagnostic); } } } }