Improve highlight locations of some BizHawk.Analyzer diagnostics
This commit is contained in:
parent
df11522190
commit
ca0ddeffef
|
@ -39,6 +39,50 @@ public static class DDExtensions
|
|||
properties: null,
|
||||
messageArgs: messageArgs));
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
Location location,
|
||||
DiagnosticSeverity effectiveSeverity,
|
||||
OAC ctx,
|
||||
string message)
|
||||
=> diag.ReportAt(location, effectiveSeverity, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
Location location,
|
||||
DiagnosticSeverity effectiveSeverity,
|
||||
SNAC ctx,
|
||||
string message)
|
||||
=> diag.ReportAt(location, effectiveSeverity, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
Location location,
|
||||
bool isErrorSeverity,
|
||||
OAC ctx,
|
||||
object?[]? messageArgs = null)
|
||||
=> diag.ReportAt(
|
||||
location,
|
||||
isErrorSeverity ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
|
||||
ctx,
|
||||
messageArgs: messageArgs);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
Location location,
|
||||
bool isErrorSeverity,
|
||||
SNAC ctx,
|
||||
object?[]? messageArgs = null)
|
||||
=> diag.ReportAt(
|
||||
location,
|
||||
isErrorSeverity ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
|
||||
ctx,
|
||||
messageArgs: messageArgs);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, Location location, OAC ctx, object?[]? messageArgs = null)
|
||||
=> ctx.ReportDiagnostic(Diagnostic.Create(diag, location, messageArgs: messageArgs));
|
||||
|
@ -47,6 +91,14 @@ public static class DDExtensions
|
|||
public static void ReportAt(this DD diag, Location location, SNAC ctx, object?[]? messageArgs = null)
|
||||
=> ctx.ReportDiagnostic(Diagnostic.Create(diag, location, messageArgs: messageArgs));
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, Location location, OAC ctx, string message)
|
||||
=> diag.ReportAt(location, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, Location location, SNAC ctx, string message)
|
||||
=> diag.ReportAt(location, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
|
@ -123,6 +175,40 @@ public static class DDExtensions
|
|||
public static void ReportAt(this DD diag, SyntaxNode location, SNAC ctx, string message)
|
||||
=> diag.ReportAt(location, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
SyntaxToken location,
|
||||
DiagnosticSeverity effectiveSeverity,
|
||||
OAC ctx,
|
||||
string message)
|
||||
=> diag.ReportAt(location.GetLocation(), effectiveSeverity, ctx, message);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
SyntaxToken location,
|
||||
DiagnosticSeverity effectiveSeverity,
|
||||
SNAC ctx,
|
||||
string message)
|
||||
=> diag.ReportAt(location.GetLocation(), effectiveSeverity, ctx, message);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, SyntaxToken location, OAC ctx, object?[]? messageArgs = null)
|
||||
=> diag.ReportAt(location.GetLocation(), ctx, messageArgs);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, SyntaxToken location, SNAC ctx, object?[]? messageArgs = null)
|
||||
=> diag.ReportAt(location.GetLocation(), ctx, messageArgs);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, SyntaxToken location, OAC ctx, string message)
|
||||
=> diag.ReportAt(location, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(this DD diag, SyntaxToken location, SNAC ctx, string message)
|
||||
=> diag.ReportAt(location, ctx, [ message ]);
|
||||
|
||||
[MI(AggressiveInlining)]
|
||||
public static void ReportAt(
|
||||
this DD diag,
|
||||
|
|
|
@ -90,6 +90,19 @@ public static class RoslynUtils
|
|||
public static bool IsEmpty(this SyntaxToken token)
|
||||
=> token.ToString().Length is 0;
|
||||
|
||||
public static Location LocWithoutReceiver(this InvocationExpressionSyntax ies)
|
||||
{
|
||||
var location = ies.GetLocation();
|
||||
if (ies.Expression is MemberAccessExpressionSyntax maes)
|
||||
{
|
||||
location = Location.Create(location.SourceTree!, location.SourceSpan.Slice(maes.Expression.Span.Length));
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public static Location LocWithoutReceiver(this IInvocationOperation operation)
|
||||
=> ((InvocationExpressionSyntax) operation.Syntax).LocWithoutReceiver();
|
||||
|
||||
public static bool Matches(this ISymbol expected, ISymbol? actual)
|
||||
=> SymbolEqualityComparer.Default.Equals(expected, actual);
|
||||
|
||||
|
@ -118,4 +131,10 @@ public static class RoslynUtils
|
|||
INamedTypeSymbol targetAttrSym,
|
||||
SyntaxNodeAnalysisContext snac)
|
||||
=> list.Matching(targetAttrSym, snac.SemanticModel, snac.CancellationToken);
|
||||
|
||||
public static TextSpan Slice(this TextSpan span, int start)
|
||||
=> TextSpan.FromBounds(start: span.Start + start, end: span.End);
|
||||
|
||||
public static TextSpan Slice(this TextSpan span, int start, int length)
|
||||
=> new(start: span.Start + start, length: length);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ public sealed class DefineCheckedOpAnalyzer : DiagnosticAnalyzer
|
|||
obsoleteAttrSym ??= snac.Compilation.GetTypeByMetadataName("System.ObsoleteAttribute")!;
|
||||
void FindCounterpartAndMaybeReport<T>(
|
||||
T declSyn,
|
||||
SyntaxToken operatorTkn,
|
||||
SyntaxList<AttributeListSyntax> attrLists,
|
||||
string checkedName,
|
||||
Func<T, string> getMethodName)
|
||||
|
@ -54,11 +55,11 @@ public sealed class DefineCheckedOpAnalyzer : DiagnosticAnalyzer
|
|||
.Any(syn => checkedName.Equals(getMethodName(syn), StringComparison.Ordinal));
|
||||
if (!hasCheckedCounterpart)
|
||||
{
|
||||
DiagDefineCheckedOp.ReportAt(declSyn, snac, ERR_MSG_MAKE_CHECKED);
|
||||
DiagDefineCheckedOp.ReportAt(operatorTkn, snac, ERR_MSG_MAKE_CHECKED);
|
||||
}
|
||||
else if (!attrLists.Matching(obsoleteAttrSym, snac).Any())
|
||||
{
|
||||
DiagDefineCheckedOp.ReportAt(declSyn, DiagnosticSeverity.Warning, snac, ERR_MSG_DEPRECATE);
|
||||
DiagDefineCheckedOp.ReportAt(operatorTkn, DiagnosticSeverity.Warning, snac, ERR_MSG_DEPRECATE);
|
||||
}
|
||||
// else usage is correct
|
||||
}
|
||||
|
@ -69,6 +70,7 @@ public sealed class DefineCheckedOpAnalyzer : DiagnosticAnalyzer
|
|||
{
|
||||
FindCounterpartAndMaybeReport(
|
||||
cods,
|
||||
cods.OperatorKeyword,
|
||||
cods.AttributeLists,
|
||||
checkedName,
|
||||
RoslynUtils.GetMethodName);
|
||||
|
@ -79,6 +81,7 @@ public sealed class DefineCheckedOpAnalyzer : DiagnosticAnalyzer
|
|||
{
|
||||
FindCounterpartAndMaybeReport(
|
||||
ods,
|
||||
ods.OperatorKeyword,
|
||||
ods.AttributeLists,
|
||||
checkedName1,
|
||||
RoslynUtils.GetMethodName);
|
||||
|
|
|
@ -48,12 +48,12 @@ public sealed class FeatureNotImplementedAnalyzer : DiagnosticAnalyzer
|
|||
void CheckBlockBody(BlockSyntax bs)
|
||||
{
|
||||
if (bs.Statements is [ ThrowStatementSyntax tss ]) MaybeReportFor(snac.SemanticModel.GetThrownExceptionType(tss), tss);
|
||||
else DiagShouldThrowNIE.ReportAt(bs.Parent!, snac, ERR_MSG_DOES_NOT_THROW);
|
||||
else DiagShouldThrowNIE.ReportAt(bs, snac, ERR_MSG_DOES_NOT_THROW);
|
||||
}
|
||||
void CheckExprBody(ArrowExpressionClauseSyntax aecs)
|
||||
{
|
||||
if (aecs.Expression is ThrowExpressionSyntax tes) MaybeReportFor(snac.SemanticModel.GetThrownExceptionType(tes), tes);
|
||||
else DiagShouldThrowNIE.ReportAt(aecs.Parent!, snac, ERR_MSG_DOES_NOT_THROW);
|
||||
else DiagShouldThrowNIE.ReportAt(aecs, snac, ERR_MSG_DOES_NOT_THROW);
|
||||
}
|
||||
void CheckAccessor(AccessorDeclarationSyntax ads)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ public sealed class FirstOrDefaultOnStructAnalyzer : DiagnosticAnalyzer
|
|||
IArrayTypeSymbol ats => ats.ElementType,
|
||||
_ => throw HawkSourceAnalyzer.ReportWTF(receiverExpr, oac, message: $"[{nameof(FirstOrDefaultOnStructAnalyzer)}] receiver parameter's effective type was of an unexpected kind (neither class/struct nor array): {receiverExprType.GetType().FullName}")
|
||||
};
|
||||
if (collectionElemType.IsValueType) DiagUseFirstOrNull.ReportAt(operation, oac);
|
||||
if (collectionElemType.IsValueType) DiagUseFirstOrNull.ReportAt(operation.LocWithoutReceiver(), oac);
|
||||
},
|
||||
OperationKind.Invocation);
|
||||
});
|
||||
|
|
|
@ -158,7 +158,15 @@ public class HawkSourceAnalyzer : DiagnosticAnalyzer
|
|||
void MaybeReportListExprSpacing(SyntaxNode listSyn, string? message)
|
||||
{
|
||||
if (message is null) return;
|
||||
DiagListExprSpacing.ReportAt(listSyn, snac, message);
|
||||
var location = listSyn.GetLocation();
|
||||
TextSpan? slice = message switch
|
||||
{
|
||||
ERR_MSG_LIST_EXPR_END => location.SourceSpan.Slice(start: location.SourceSpan.Length - 1),
|
||||
ERR_MSG_LIST_EXPR_START => location.SourceSpan.Slice(start: 0, length: 1),
|
||||
_ => null
|
||||
};
|
||||
if (slice is not null) location = Location.Create(location.SourceTree!, slice.Value);
|
||||
DiagListExprSpacing.ReportAt(location, snac, message);
|
||||
}
|
||||
switch (snac.Node)
|
||||
{
|
||||
|
@ -179,7 +187,8 @@ public class HawkSourceAnalyzer : DiagnosticAnalyzer
|
|||
CheckSpacingInList(ces.Elements, ces.OpenBracketToken, ces.ToString));
|
||||
break;
|
||||
case InterpolatedStringExpressionSyntax ises:
|
||||
if (ises.StringStartToken.Text[0] is '@') DiagInterpStringIsDollarAt.ReportAt(ises, snac);
|
||||
var interpTkn = ises.StringStartToken;
|
||||
if (interpTkn.Text[0] is '@') DiagInterpStringIsDollarAt.ReportAt(interpTkn, snac);
|
||||
break;
|
||||
case ListPatternSyntax lps:
|
||||
MaybeReportListExprSpacing(
|
||||
|
@ -190,7 +199,7 @@ public class HawkSourceAnalyzer : DiagnosticAnalyzer
|
|||
DiagNoQueryExpression.ReportAt(snac.Node, snac);
|
||||
break;
|
||||
case RecordDeclarationSyntax rds when rds.ClassOrStructKeyword.ToString() is not "class": // `record struct`s don't use this kind
|
||||
DiagRecordImplicitlyRefType.ReportAt(rds, snac);
|
||||
DiagRecordImplicitlyRefType.ReportAt(rds.Keyword, snac);
|
||||
break;
|
||||
case SwitchExpressionArmSyntax { WhenClause: null, Pattern: DiscardPatternSyntax, Expression: ThrowExpressionSyntax tes }:
|
||||
var thrownExceptionType = snac.SemanticModel.GetThrownExceptionType(tes);
|
||||
|
|
|
@ -119,7 +119,11 @@ public sealed class LINQOnStringsAnalyzer : DiagnosticAnalyzer
|
|||
: "Use `str.Contains(c.ToString())`";
|
||||
break;
|
||||
}
|
||||
DiagLINQOnStrings.ReportAt(operation, level, oac, string.Format(msgFmtStr, receiverExpr.Syntax));
|
||||
DiagLINQOnStrings.ReportAt(
|
||||
operation.LocWithoutReceiver(),
|
||||
level,
|
||||
oac,
|
||||
string.Format(msgFmtStr, receiverExpr.Syntax));
|
||||
},
|
||||
OperationKind.Invocation);
|
||||
});
|
||||
|
|
|
@ -39,7 +39,10 @@ public sealed class TryGetValueImplicitDiscardAnalyzer : DiagnosticAnalyzer
|
|||
var calledSym = operation.TargetMethod.ConstructedFrom;
|
||||
if (calledSym.Name is STR_TGV)
|
||||
{
|
||||
DiagUncheckedTryGetValue.ReportAt(operation, isErrorSeverity: IsBCLTryGetValue(calledSym), oac);
|
||||
DiagUncheckedTryGetValue.ReportAt(
|
||||
operation.LocWithoutReceiver(),
|
||||
isErrorSeverity: IsBCLTryGetValue(calledSym),
|
||||
oac);
|
||||
}
|
||||
},
|
||||
OperationKind.Invocation);
|
||||
|
|
|
@ -19,23 +19,23 @@ public sealed class DefineCheckedOpAnalyzerTests
|
|||
public struct GF7 {
|
||||
private static readonly int[] Inverses = [ -1, 1, 4, 5, 2, 3, 6 ];
|
||||
public static GF7 operator checked -(GF7 x) => new(-x._value); // the most useless but here for completeness
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ -(GF7 x) => new(-x._value % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ -(GF7 x) => new(-x._value % 7);
|
||||
public static GF7 operator checked ++(GF7 x) => new(x._value + 1);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ ++(GF7 x) => new((x._value + 1) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ ++(GF7 x) => new((x._value + 1) % 7);
|
||||
public static GF7 operator checked --(GF7 x) => new(x._value - 1);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ --(GF7 x) => new((x._value - 1) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ --(GF7 x) => new((x._value - 1) % 7);
|
||||
public static GF7 operator checked +(GF7 x, GF7 y) => new(x._value + y._value);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ +(GF7 x, GF7 y) => new((x._value + y._value) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ +(GF7 x, GF7 y) => new((x._value + y._value) % 7);
|
||||
public static GF7 operator checked +(GF7 x, int y) => new(x._value + y);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ +(GF7 x, int y) => new((x._value + y) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ +(GF7 x, int y) => new((x._value + y) % 7);
|
||||
public static GF7 operator checked -(GF7 minuend, int subtrahend) => new(minuend._value - subtrahend);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ -(GF7 minuend, int subtrahend) => new((minuend._value - subtrahend) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ -(GF7 minuend, int subtrahend) => new((minuend._value - subtrahend) % 7);
|
||||
public static GF7 operator checked *(GF7 x, int y) => new(x._value * y);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ *(GF7 x, int y) => new((x._value * y) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ *(GF7 x, int y) => new((x._value * y) % 7);
|
||||
public static GF7 operator checked /(GF7 dividend, GF7 divisor) => new((dividend._value * Inverses[divisor._value]) % 7);
|
||||
{|BHI1300:public static GF7 operator /*unchecked*/ /(GF7 dividend, GF7 divisor) => divisor._value is 0 ? default : new((dividend._value * Inverses[divisor._value]) % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} /*unchecked*/ /(GF7 dividend, GF7 divisor) => divisor._value is 0 ? default : new((dividend._value * Inverses[divisor._value]) % 7);
|
||||
public static explicit operator checked GF7(int n) => new(n);
|
||||
{|BHI1300:public static explicit operator /*unchecked*/ GF7(int n) => new(n % 7);|}
|
||||
public static explicit {|BHI1300:operator|} /*unchecked*/ GF7(int n) => new(n % 7);
|
||||
private byte _value;
|
||||
public byte Value {
|
||||
get => _value;
|
||||
|
@ -55,15 +55,15 @@ public sealed class DefineCheckedOpAnalyzerTests
|
|||
using System;
|
||||
public struct GF7 {
|
||||
private static readonly int[] Inverses = [ -1, 1, 4, 5, 2, 3, 6 ];
|
||||
{|BHI1300:public static GF7 operator -(GF7 x) => new(-x._value % 7);|}
|
||||
{|BHI1300:public static GF7 operator ++(GF7 x) => new((x._value + 1) % 7);|}
|
||||
{|BHI1300:public static GF7 operator --(GF7 x) => new((x._value - 1) % 7);|}
|
||||
{|BHI1300:public static GF7 operator +(GF7 x, GF7 y) => new((x._value + y._value) % 7);|}
|
||||
{|BHI1300:public static GF7 operator +(GF7 x, int y) => new((x._value + y) % 7);|}
|
||||
{|BHI1300:public static GF7 operator -(GF7 minuend, int subtrahend) => new((minuend._value - subtrahend) % 7);|}
|
||||
{|BHI1300:public static GF7 operator *(GF7 x, int y) => new((x._value * y) % 7);|}
|
||||
{|BHI1300:public static GF7 operator /(GF7 dividend, GF7 divisor) => divisor._value is 0 ? default : new((dividend._value * Inverses[divisor._value]) % 7);|}
|
||||
{|BHI1300:public static explicit operator GF7(int n) => new(n % 7);|}
|
||||
public static GF7 {|BHI1300:operator|} -(GF7 x) => new(-x._value % 7);
|
||||
public static GF7 {|BHI1300:operator|} ++(GF7 x) => new((x._value + 1) % 7);
|
||||
public static GF7 {|BHI1300:operator|} --(GF7 x) => new((x._value - 1) % 7);
|
||||
public static GF7 {|BHI1300:operator|} +(GF7 x, GF7 y) => new((x._value + y._value) % 7);
|
||||
public static GF7 {|BHI1300:operator|} +(GF7 x, int y) => new((x._value + y) % 7);
|
||||
public static GF7 {|BHI1300:operator|} -(GF7 minuend, int subtrahend) => new((minuend._value - subtrahend) % 7);
|
||||
public static GF7 {|BHI1300:operator|} *(GF7 x, int y) => new((x._value * y) % 7);
|
||||
public static GF7 {|BHI1300:operator|} /(GF7 dividend, GF7 divisor) => divisor._value is 0 ? default : new((dividend._value * Inverses[divisor._value]) % 7);
|
||||
public static explicit {|BHI1300:operator|} GF7(int n) => new(n % 7);
|
||||
private byte _value;
|
||||
public byte Value {
|
||||
get => _value;
|
||||
|
|
|
@ -20,13 +20,13 @@ public sealed class FeatureNotImplementedAnalyzerTests
|
|||
}
|
||||
[FeatureNotImplemented] private static int Z()
|
||||
=> throw new NotImplementedException();
|
||||
{|BHI3300:[FeatureNotImplemented] private static int A => default;|}
|
||||
[FeatureNotImplemented] private static int A {|BHI3300:=> default|};
|
||||
private static int B {
|
||||
{|BHI3300:[FeatureNotImplemented] get => default;|}
|
||||
{|BHI3300:[FeatureNotImplemented] set => _ = value;|}
|
||||
[FeatureNotImplemented] get {|BHI3300:=> default|};
|
||||
[FeatureNotImplemented] set {|BHI3300:=> _ = value|};
|
||||
}
|
||||
{|BHI3300:[FeatureNotImplemented] private static int C()
|
||||
=> default;|}
|
||||
[FeatureNotImplemented] private static int C()
|
||||
{|BHI3300:=> default|};
|
||||
// wrong exception type, same code but different message:
|
||||
[FeatureNotImplemented] private static int D => {|BHI3300:throw new InvalidOperationException()|};
|
||||
private static int E {
|
||||
|
|
|
@ -18,13 +18,13 @@ public sealed class FirstOrDefaultOnStructAnalyzerTests
|
|||
private static string? Z()
|
||||
=> new List<int> { 0x80, 0x20, 0x40 }.Select(static n => n.ToString()).FirstOrDefault();
|
||||
private static int A()
|
||||
=> {|BHI3100:new[] { 0x80, 0x20, 0x40 }.FirstOrDefault()|};
|
||||
=> new[] { 0x80, 0x20, 0x40 }{|BHI3100:.FirstOrDefault()|};
|
||||
private static int B()
|
||||
=> {|BHI3100:new List<int> { 0x80, 0x20, 0x40 }.FirstOrDefault()|};
|
||||
=> new List<int> { 0x80, 0x20, 0x40 }{|BHI3100:.FirstOrDefault()|};
|
||||
private static int C()
|
||||
=> {|BHI3100:new[] { 0x80, 0x20, 0x40 }.FirstOrDefault(static n => n.ToString().Length > 2)|};
|
||||
=> new[] { 0x80, 0x20, 0x40 }{|BHI3100:.FirstOrDefault(static n => n.ToString().Length > 2)|};
|
||||
private static int D()
|
||||
=> {|BHI3100:new List<int> { 0x80, 0x20, 0x40 }.FirstOrDefault(static n => n.ToString().Length > 2)|};
|
||||
=> new List<int> { 0x80, 0x20, 0x40 }{|BHI3100:.FirstOrDefault(static n => n.ToString().Length > 2)|};
|
||||
}
|
||||
namespace BizHawk.Common.CollectionExtensions {
|
||||
public static class CollectionExtensions {} // Analyzer short-circuits if this doesn't exist, since that's where the extension lives
|
||||
|
|
|
@ -106,7 +106,7 @@ public sealed class HawkSourceAnalyzerTests
|
|||
=> Verify.VerifyAnalyzerAsync("""
|
||||
public static class Cases {
|
||||
private static readonly int Z = $@"{0x100}".Length;
|
||||
private static readonly int A = {|BHI1004:@$"{0x100}"|}.Length;
|
||||
private static readonly int A = {|BHI1004:@$"|}{0x100}".Length;
|
||||
}
|
||||
""");
|
||||
|
||||
|
@ -119,9 +119,9 @@ public sealed class HawkSourceAnalyzerTests
|
|||
private static readonly int[] X = W ? [ ] : V;
|
||||
private static readonly int[] Y = [ 0x80, 0x20, 0x40 ];
|
||||
private static readonly bool Z = Y is [ _, > 20, .. ];
|
||||
private static readonly int[] A = {|BHI1110:[0x80, 0x20, 0x40 ]|};
|
||||
private static readonly bool B = A is {|BHI1110:[ _, > 20, ..]|};
|
||||
private static readonly bool C = A is {|BHI1110:[_, > 20, ..]|};
|
||||
private static readonly int[] A = {|BHI1110:[|}0x80, 0x20, 0x40 ];
|
||||
private static readonly bool B = A is [ _, > 20, ..{|BHI1110:]|};
|
||||
private static readonly bool C = A is [_, > 20, ..{|BHI1110:]|}; // the way this is written, it will flag end and then start
|
||||
private static readonly int[] D = {|BHI1110:[]|};
|
||||
private static readonly bool E = D is {|BHI1110:[]|};
|
||||
private static readonly int[] F = E ? {|BHI1110:[]|} : D;
|
||||
|
@ -133,7 +133,7 @@ public sealed class HawkSourceAnalyzerTests
|
|||
=> Verify.VerifyAnalyzerAsync("""
|
||||
internal record struct Y {}
|
||||
internal record class Z {}
|
||||
{|BHI1130:internal record A {}|}
|
||||
internal {|BHI1130:record|} A {}
|
||||
""");
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -36,49 +36,49 @@ public sealed class LINQOnStringsAnalyzerTests
|
|||
private static bool ZZ(string str)
|
||||
=> str.All(DummyPredicate);
|
||||
private static bool AA(string str)
|
||||
=> {|BHI3102:str.Any()|};
|
||||
=> str{|BHI3102:.Any()|};
|
||||
private static IEnumerable<char> AB(string str)
|
||||
=> {|BHI3102:str.Append('.')|};
|
||||
=> str{|BHI3102:.Append('.')|};
|
||||
private static IEnumerable<char> AC(string str)
|
||||
=> {|BHI3102:str.Concat("-_-")|};
|
||||
=> str{|BHI3102:.Concat("-_-")|};
|
||||
private static IEnumerable<char> AD(string str)
|
||||
=> {|BHI3102:str.Concat(new[] { '-', '_', '-' })|};
|
||||
=> str{|BHI3102:.Concat(new[] { '-', '_', '-' })|};
|
||||
private static bool AE(string str)
|
||||
=> {|BHI3102:Enumerable.Contains(str, '.')|};
|
||||
=> Enumerable{|BHI3102:.Contains(str, '.')|};
|
||||
private static int AF(string str)
|
||||
=> {|BHI3102:str.Count()|};
|
||||
=> str{|BHI3102:.Count()|};
|
||||
private static IEnumerable<char> AG(string str)
|
||||
=> {|BHI3102:str.DefaultIfEmpty()|};
|
||||
=> str{|BHI3102:.DefaultIfEmpty()|};
|
||||
private static IEnumerable<char> AH(string str)
|
||||
=> {|BHI3102:str.DefaultIfEmpty('.')|};
|
||||
=> str{|BHI3102:.DefaultIfEmpty('.')|};
|
||||
private static char AI(string str)
|
||||
=> {|BHI3102:str.ElementAt(2)|};
|
||||
=> str{|BHI3102:.ElementAt(2)|};
|
||||
private static char AJ(string str)
|
||||
=> {|BHI3102:str.ElementAtOrDefault(2)|};
|
||||
=> str{|BHI3102:.ElementAtOrDefault(2)|};
|
||||
private static char AK(string str)
|
||||
=> {|BHI3102:str.First()|};
|
||||
=> str{|BHI3102:.First()|};
|
||||
private static char AL(string str)
|
||||
=> {|BHI3102:str.FirstOrDefault()|};
|
||||
=> str{|BHI3102:.FirstOrDefault()|};
|
||||
private static char AM(string str)
|
||||
=> {|BHI3102:str.Last()|};
|
||||
=> str{|BHI3102:.Last()|};
|
||||
private static char AN(string str)
|
||||
=> {|BHI3102:str.LastOrDefault()|};
|
||||
=> str{|BHI3102:.LastOrDefault()|};
|
||||
private static long AO(string str)
|
||||
=> {|BHI3102:str.LongCount()|};
|
||||
=> str{|BHI3102:.LongCount()|};
|
||||
private static IEnumerable<char> AP(string str)
|
||||
=> {|BHI3102:str.Prepend('.')|};
|
||||
=> str{|BHI3102:.Prepend('.')|};
|
||||
private static IEnumerable<char> AQ(string str)
|
||||
=> {|BHI3102:str.Reverse()|};
|
||||
=> str{|BHI3102:.Reverse()|};
|
||||
private static char AR(string str)
|
||||
=> {|BHI3102:str.Single()|};
|
||||
=> str{|BHI3102:.Single()|};
|
||||
private static char AS(string str)
|
||||
=> {|BHI3102:str.SingleOrDefault()|};
|
||||
=> str{|BHI3102:.SingleOrDefault()|};
|
||||
private static IEnumerable<char> AT(string str)
|
||||
=> {|BHI3102:str.Skip(2)|};
|
||||
=> str{|BHI3102:.Skip(2)|};
|
||||
private static IEnumerable<char> AU(string str)
|
||||
=> {|BHI3102:str.Take(2)|};
|
||||
=> str{|BHI3102:.Take(2)|};
|
||||
private static char[] AV(string str)
|
||||
=> {|BHI3102:str.ToArray()|};
|
||||
=> str{|BHI3102:.ToArray()|};
|
||||
}
|
||||
namespace BizHawk.Common.StringExtensions {
|
||||
public static class StringExtensions {} // Analyzer does more checks if this exists
|
||||
|
|
|
@ -23,13 +23,13 @@ public sealed class TryGetValueImplicitDiscardAnalyzerTests
|
|||
private static void Z()
|
||||
=> _ = MakeDict().TryGetValue("z", out _);
|
||||
private static void A()
|
||||
=> {|BHI1200:MakeDict().TryGetValue("a", out _)|};
|
||||
=> MakeDict(){|BHI1200:.TryGetValue("a", out _)|};
|
||||
private static void B()
|
||||
=> {|BHI1200:((IDictionary<string, int>) MakeDict()).TryGetValue("b", out _)|};
|
||||
=> ((IDictionary<string, int>) MakeDict()){|BHI1200:.TryGetValue("b", out _)|};
|
||||
private static void C()
|
||||
=> {|BHI1200:((IReadOnlyDictionary<string, int>) MakeDict()).TryGetValue("c", out _)|};
|
||||
=> ((IReadOnlyDictionary<string, int>) MakeDict()){|BHI1200:.TryGetValue("c", out _)|};
|
||||
private static void D()
|
||||
=> {|BHI1200:new CustomDict<string, int>().TryGetValue("d", out _)|};
|
||||
=> new CustomDict<string, int>(){|BHI1200:.TryGetValue("d", out _)|};
|
||||
}
|
||||
""");
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue