This instance will be upgraded to Heptapod 0.17.0 on 2020-11-26 at 14:00 UTC+1 (a few minutes of down time)

Commit 86ac22d4 authored by Jesse McGrew's avatar Jesse McGrew

Various .NET Core cleanup recommended by analyzers and Sharper.

parent 62ba0b9cc06c
......@@ -56,25 +56,18 @@ namespace ZilfAnalyzers.Test.Helpers
[JetBrains.Annotations.NotNull]
static string ToSafeString(this char c)
{
switch (c)
return c switch
{
case '\r':
return @"\r";
case '\n':
return @"\n";
case '\t':
return @"\t";
case '\a':
return @"\a";
case '\v':
return @"\v";
case '\f':
return @"\f";
default:
return char.IsControl(c) || char.IsWhiteSpace(c)
? $"\\u{(int)c:X};"
: c.ToString(CultureInfo.InvariantCulture);
}
'\r' => @"\r",
'\n' => @"\n",
'\t' => @"\t",
'\a' => @"\a",
'\v' => @"\v",
'\f' => @"\f",
_ => char.IsControl(c) || char.IsWhiteSpace(c)
? $"\\u{(int)c:X};"
: c.ToString(CultureInfo.InvariantCulture),
};
}
}
......
......@@ -40,9 +40,17 @@ namespace ZilfAnalyzers.Test.Helpers
/// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
/// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
/// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("AsyncUsage", "AsyncFixer01:Unnecessary async/await usage", Justification = "VS template code")]
protected async Task VerifyCSharpFixAsync(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false)
{
await VerifyFixAsync(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics);
await VerifyFixAsync(LanguageNames.CSharp,
GetCSharpDiagnosticAnalyzer(),
GetCSharpCodeFixProvider(),
oldSource,
newSource,
codeFixIndex,
allowNewCompilerDiagnostics)
.ConfigureAwait(false);
}
/// <summary>
......@@ -52,9 +60,17 @@ namespace ZilfAnalyzers.Test.Helpers
/// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
/// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
/// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("AsyncUsage", "AsyncFixer01:Unnecessary async/await usage", Justification = "VS template code")]
protected async Task VerifyBasicFixAsync(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false)
{
await VerifyFixAsync(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics);
await VerifyFixAsync(LanguageNames.VisualBasic,
GetBasicDiagnosticAnalyzer(),
GetBasicCodeFixProvider(),
oldSource,
newSource,
codeFixIndex,
allowNewCompilerDiagnostics)
.ConfigureAwait(false);
}
/// <summary>
......@@ -85,21 +101,21 @@ namespace ZilfAnalyzers.Test.Helpers
for (int i = 0; i < attempts; ++i)
{
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, _) => actions.Add(a), CancellationToken.None);
await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
if (!actions.Any())
if (actions.Count == 0)
{
break;
}
if (codeFixIndex != null)
{
document = ApplyFix(document, actions.ElementAt((int)codeFixIndex));
document = ApplyFix(document, actions[(int)codeFixIndex]);
break;
}
document = ApplyFix(document, actions.ElementAt(0));
document = ApplyFix(document, actions[0]);
analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzer, new[] { document }).ConfigureAwait(false);
analyzerDiagnostics = analyzerDiagnostics.Where(d => fixableIds.Contains(d.Id)).ToArray();
......@@ -109,17 +125,17 @@ namespace ZilfAnalyzers.Test.Helpers
if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
{
// Format and get the compiler diagnostics again so that the locations make sense in the output
document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
document = document.WithSyntaxRoot(Formatter.Format(await document.GetSyntaxRootAsync().ConfigureAwait(false), Formatter.Annotation, document.Project.Solution.Workspace));
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
Assert.Fail(
"Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
document.GetSyntaxRootAsync().Result.ToFullString());
(await document.GetSyntaxRootAsync().ConfigureAwait(false)).ToFullString());
}
//check if there are analyzer diagnostics left after the code fix
if (!analyzerDiagnostics.Any())
if (analyzerDiagnostics.Length == 0)
{
break;
}
......
......@@ -46,7 +46,7 @@ namespace Dezapf
}
}
class DataChunk : Chunk
sealed class DataChunk : Chunk
{
public byte[] Bytes { get; }
......@@ -137,7 +137,7 @@ namespace Dezapf
}
}
class GlobalsChunk : Chunk
sealed class GlobalsChunk : Chunk
{
public ushort[] Values { get; }
......@@ -150,7 +150,7 @@ namespace Dezapf
public static GlobalsChunk FromStream(Stream stream, int offset, int length)
{
stream.Seek(offset, SeekOrigin.Begin);
BinaryReader rdr = new BinaryReader(stream);
var rdr = new BinaryReader(stream);
int count = length / 2;
ushort[] values = new ushort[count];
for (int i = 0; i < count; i++)
......
......@@ -165,7 +165,7 @@ namespace Dezapf
{
System.Diagnostics.Debug.Assert(zversion >= 3);
StringBuilder sb = new StringBuilder(encodedText.Length * 3);
var sb = new StringBuilder(encodedText.Length * 3);
int mode = 0; // 0/1/2 = alphabets, 3 = ASCII state 1, 4 = ASCII state 2
int pendingAscii = 0;
......
......@@ -132,18 +132,13 @@ namespace Dezapf
class HeaderChunk : Chunk
{
readonly Header hdr;
public HeaderChunk(int pc, int length, Header hdr)
: base(pc, length)
{
this.hdr = hdr;
Header = hdr;
}
public Header Header
{
get { return hdr; }
}
public Header Header { get; }
public override void WriteTo(TextWriter writer, Context ctx)
{
......
......@@ -41,7 +41,7 @@ namespace Dezapf
ShortPositive = 0xc0,
}
class Instruction : Chunk
sealed class Instruction : Chunk
{
ushort op;
ushort[] operands;
......@@ -204,7 +204,7 @@ namespace Dezapf
ushort[] encodedText = null;
if ((attr.Flags & ZOpFlags.String) != 0)
{
List<ushort> list = new List<ushort>();
var list = new List<ushort>();
ushort w;
do
{
......
......@@ -39,7 +39,7 @@ namespace Dezapf
protected string FormatFlags1(Context ctx, byte flags1)
{
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
if (ctx.ZVersion <= 3)
{
if ((flags1 & 1) != 0)
......
This diff is collapsed.
......@@ -67,12 +67,7 @@ namespace Dezapf
}
}
readonly List<Range> list;
public RangeList()
{
list = new List<Range>();
}
readonly List<Range> list = new List<Range>();
public void Add(Range range)
{
......@@ -106,7 +101,7 @@ namespace Dezapf
{
if (list.Count > 0)
{
Range r = new Range(position, 0, default(T));
var r = new Range(position, 0, default);
int idx = list.BinarySearch(r);
if (idx < 0)
......@@ -133,7 +128,7 @@ namespace Dezapf
}
}
value = default(T);
value = default;
return false;
}
......
......@@ -325,7 +325,6 @@ General switches:
-c #### set creator version
-ab also optimize abbreviations and print ZAPF code
-dx use XML debug format");
}
/// <exception cref="FatalError">An <see cref="IOException"/> occurred while reading the input file(s).</exception>
......@@ -1314,7 +1313,7 @@ General switches:
break;
case DebugArrayDirective darr:
if (ctx.GlobalSymbols.TryGetValue("GLOBAL", out var sym1) == false)
if (!ctx.GlobalSymbols.TryGetValue("GLOBAL", out var sym1))
{
Errors.Serious(ctx, node, "define GLOBAL before using .DEBUG-ARRAY");
return;
......@@ -1450,7 +1449,7 @@ General switches:
AlignRoutine(ctx);
int paddr = (ctx.Position - ctx.FunctionsOffset) / ctx.PackingDivisor;
if (ctx.GlobalSymbols.TryGetValue(name, out var sym) == false)
if (!ctx.GlobalSymbols.TryGetValue(name, out var sym))
{
sym = new Symbol(name, SymbolType.Function, paddr);
ctx.GlobalSymbols.Add(name, sym);
......@@ -1523,7 +1522,7 @@ General switches:
AlignString(ctx);
int paddr = (ctx.Position - ctx.StringsOffset) / ctx.PackingDivisor;
if (ctx.GlobalSymbols.TryGetValue(name, out var sym) == false)
if (!ctx.GlobalSymbols.TryGetValue(name, out var sym))
{
sym = new Symbol(name, SymbolType.String, paddr);
ctx.GlobalSymbols.Add(name, sym);
......@@ -1731,8 +1730,8 @@ General switches:
}
else
{
if ((ctx.LocalSymbols.TryGetValue(node.StoreTarget, out var sym) == false &&
ctx.GlobalSymbols.TryGetValue(node.StoreTarget, out sym) == false) ||
if (!ctx.LocalSymbols.TryGetValue(node.StoreTarget, out var sym) &&
!ctx.GlobalSymbols.TryGetValue(node.StoreTarget, out sym) ||
sym!.Type != SymbolType.Variable)
{
Errors.ThrowSerious(node, "expected local or global variable as store target");
......@@ -1819,6 +1818,8 @@ General switches:
void CheckMismatch()
{
Debug.Assert(sym != null);
if (sym.Value == expected)
return;
......@@ -1857,7 +1858,7 @@ General switches:
Errors.ThrowSerious(node, "local labels not allowed outside a function");
name = localNode.Name;
if (ctx.LocalSymbols.TryGetValue(name, out sym) == false)
if (!ctx.LocalSymbols.TryGetValue(name, out sym))
{
if (ctx.CausesReassembly(name))
nodeIndex = ctx.Reassemble(name) - 1;
......
......@@ -726,7 +726,7 @@ namespace Zilf.Emit
var newLine = new Line(
null,
Combiner == null ? default : Combiner.SynthesizeBranchAlways(),
Combiner == null ? default! : Combiner.SynthesizeBranchAlways(),
line.TargetLabel,
PeepholeLineType.BranchAlways)
{
......
......@@ -31,20 +31,13 @@ namespace Zilf.Emit.Zap
public static AsmExpr ToAsmExpr(this IOperand operand)
{
switch (operand)
return operand switch
{
case NumericOperand num:
return new NumericLiteral(num.Value);
case IndirectOperand indirect:
return new QuoteExpr(indirect.Variable.ToAsmExpr());
case SumOperand sum:
return new AdditionExpr(sum.Left.ToAsmExpr(), sum.Right.ToAsmExpr());
default:
return new SymbolExpr(operand.ToString());
}
NumericOperand num => (AsmExpr)new NumericLiteral(num.Value),
IndirectOperand indirect => new QuoteExpr(indirect.Variable.ToAsmExpr()),
SumOperand sum => new AdditionExpr(sum.Left.ToAsmExpr(), sum.Right.ToAsmExpr()),
_ => new SymbolExpr(operand.ToString())
};
}
public static bool IsStack(this AsmExpr asmExpr) => asmExpr is SymbolExpr sym && sym.Text == "STACK";
......
......@@ -172,7 +172,6 @@ namespace Zilf.Compiler.Builtins
void InnerError(string msg)
{
Debug.Assert(msg != null, nameof(msg) + " != null");
error(i, msg);
}
......@@ -681,31 +680,16 @@ namespace Zilf.Compiler.Builtins
out Func<ValueCall, IOperand, IOperand, IOperand> compileUnary)
{
// a delegate implementing the actual arithmetic operation
#pragma warning disable IDE0066 // Convert switch statement to expression
switch (op)
#pragma warning restore IDE0066 // Convert switch statement to expression
{
case BinaryOp.Add:
operation = (a, b) => (short)(a + b);
break;
case BinaryOp.Sub:
operation = (a, b) => (short)(a - b);
break;
case BinaryOp.Mul:
operation = (a, b) => (short)(a * b);
break;
case BinaryOp.Div:
operation = (a, b) => (short)(a / b);
break;
case BinaryOp.And:
operation = (a, b) => (short)(a & b);
break;
case BinaryOp.Or:
operation = (a, b) => (short)(a | b);
break;
default:
throw new ArgumentOutOfRangeException(nameof(op), op, null);
}
operation = op switch
{
BinaryOp.Add => (Func<short, short, short>)((a, b) => (short)(a + b)),
BinaryOp.Sub => (a, b) => (short)(a - b),
BinaryOp.Mul => (a, b) => (short)(a * b),
BinaryOp.Div => (a, b) => (short)(a / b),
BinaryOp.And => (a, b) => (short)(a & b),
BinaryOp.Or => (a, b) => (short)(a | b),
_ => throw new ArgumentOutOfRangeException(nameof(op), op, null)
};
// the initial value, which is returned as-is if there are no args,
// or possibly combined with the single arg if there's only one
......@@ -827,19 +811,12 @@ namespace Zilf.Compiler.Builtins
public static IOperand RestOp(ValueCall c, IOperand left, IOperand? right = null)
{
// if left and right are constants, we can add them at assembly time
if (left is IConstantOperand lconst)
return (left, right) switch
{
switch (right)
{
case IConstantOperand rconst:
return lconst.Add(rconst);
case null:
return lconst.Add(c.cc.Game.One);
}
}
return ArithmeticOp(c, BinaryOp.Add, left, right ?? c.cc.Game.One);
(IConstantOperand lconst, IConstantOperand rconst) => lconst.Add(rconst),
(IConstantOperand lconst, null) => lconst.Add(c.cc.Game.One),
_ => ArithmeticOp(c, BinaryOp.Add, left, right ?? c.cc.Game.One),
};
}
[Builtin("BACK", "ZBACK")]
......
......@@ -340,7 +340,7 @@ namespace Zilf.Compiler
var endLabel = rb.DefineLabel();
bool elsePart = false;
resultStorage = resultStorage ?? rb.Stack;
resultStorage ??= rb.Stack;
while (!clauses.IsEmpty)
{
ZilObject clause, origCondition, condition;
......
......@@ -271,17 +271,12 @@ namespace Zilf.Compiler
static ZilAtom? GetUninitializedAtomFromBindingListItem(ZilObject zo)
{
// ReSharper disable once SwitchStatementMissingSomeCases
switch (zo.StdTypeAtom)
return zo.StdTypeAtom switch
{
case StdAtom.ATOM:
return (ZilAtom)zo;
case StdAtom.ADECL:
return ((ZilAdecl)zo).First as ZilAtom;
default:
return null;
}
StdAtom.ATOM => (ZilAtom)zo,
StdAtom.ADECL => (((ZilAdecl)zo).First as ZilAtom),
_ => null
};
}
static bool RecursivelyContains(ZilObject haystack, ZilObject needle)
......
......@@ -215,11 +215,7 @@ namespace Zilf.Compiler
compilation.PopInnerLocal(tempAtom);
}
public int Count
{
[System.Diagnostics.Contracts.Pure]
get => values.Length;
}
public int Count => values.Length;
public IOperand this[int index] => values[index];
......
......@@ -207,16 +207,15 @@ namespace Zilf.Compiler
public static T FirstOrCombine<T>(this IEnumerable<T> sequence, SequenceCombiner<T> combiner)
{
using (var tor = sequence.GetEnumerator())
{
if (!tor.MoveNext())
throw new InvalidOperationException("No items in sequence");
using var tor = sequence.GetEnumerator();
var first = tor.Current;
Debug.Assert(first != null);
if (!tor.MoveNext())
throw new InvalidOperationException("No items in sequence");
return tor.MoveNext() ? combiner(ReconstructSequence(first, tor)) : first;
}
var first = tor.Current;
Debug.Assert(first != null);
return tor.MoveNext() ? combiner(ReconstructSequence(first, tor)) : first;
}
}
}
......@@ -249,54 +249,53 @@ namespace Zilf.Compiler
Debug.Assert(!wantCompile || outputFileName != null);
// open input file
using (var inputStream = OpenFile(inputFileName, false))
using var inputStream = OpenFile(inputFileName, false);
// evaluate source text
using (ctx.PushFileContext(inputFileName))
{
// evaluate source text
using (ctx.PushFileContext(inputFileName))
ctx.InterceptOpenFile = OpenFile;
ctx.InterceptFileExists = CheckFileExists;
ctx.IncludePaths.AddRange(IncludePaths);
try
{
Program.Evaluate(ctx, inputStream);
}
catch (ZilErrorBase ex)
{
ctx.HandleError(ex);
}
// compile, if there were no evaluation errors
if (wantCompile && ctx.ErrorCount == 0)
{
ctx.InterceptOpenFile = OpenFile;
ctx.InterceptFileExists = CheckFileExists;
ctx.IncludePaths.AddRange(IncludePaths);
Debug.Assert(outputFileName != null);
ctx.RunHook("PRE-COMPILE");
ctx.SetDefaultConstants();
try
{
Program.Evaluate(ctx, inputStream);
var zversion = ctx.ZEnvironment.ZVersion;
var streamFactory = new ZapStreamFactory(this, outputFileName);
var options = MakeGameOptions(ctx);
using var gameBuilder = new GameBuilder(zversion, streamFactory, wantDebugInfo, options);
Compilation.Compile(ctx, gameBuilder);
}
catch (ZilErrorBase ex)
catch (ZilErrorBase ex) // catch fatals too
{
ctx.HandleError(ex);
}
// compile, if there were no evaluation errors
if (wantCompile && ctx.ErrorCount == 0)
{
Debug.Assert(outputFileName != null);
ctx.RunHook("PRE-COMPILE");
ctx.SetDefaultConstants();
try
{
var zversion = ctx.ZEnvironment.ZVersion;
var streamFactory = new ZapStreamFactory(this, outputFileName);
var options = MakeGameOptions(ctx);
using var gameBuilder = new GameBuilder(zversion, streamFactory, wantDebugInfo, options);
Compilation.Compile(ctx, gameBuilder);
}
catch (ZilErrorBase ex) // catch fatals too
{
ctx.HandleError(ex);
}
}
}
result.ErrorCount = ctx.ErrorCount;
result.WarningCount = ctx.WarningCount;
result.SuppressedWarningCount = ctx.SuppressedWarningCount;
result.Success = (ctx.ErrorCount == 0);
result.Diagnostics = ctx.Diagnostics;
return result;
}
result.ErrorCount = ctx.ErrorCount;
result.WarningCount = ctx.WarningCount;
result.SuppressedWarningCount = ctx.SuppressedWarningCount;
result.Success = (ctx.ErrorCount == 0);
result.Diagnostics = ctx.Diagnostics;
return result;
}
static GameOptions MakeGameOptions(Context ctx)
......
......@@ -38,30 +38,24 @@ namespace Zilf.Compiler
{
public static LocalBindingType ToLocalBindingType(this ArgItem.ArgType argType)
{
switch (argType)
return argType switch
{
case ArgItem.ArgType.Required:
return LocalBindingType.RoutineRequired;
case ArgItem.ArgType.Optional:
return LocalBindingType.RoutineOptional;
case ArgItem.ArgType.Auxiliary:
return LocalBindingType.RoutineAuxiliary;
default:
throw new ArgumentOutOfRangeException(nameof(argType), argType, null);
}
ArgItem.ArgType.Required => LocalBindingType.RoutineRequired,
ArgItem.ArgType.Optional => LocalBindingType.RoutineOptional,
ArgItem.ArgType.Auxiliary => LocalBindingType.RoutineAuxiliary,
_ => throw new ArgumentOutOfRangeException(nameof(argType), argType, null)
};