Browse Source

Merge pull request #3187 from icsharpcode/feature/roslyn492

Update to Roslyn 4.9.2
pull/3191/head
Siegfried Pammer 1 year ago committed by GitHub
parent
commit
afbc65d14d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      Directory.Packages.props
  2. 4
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs
  3. 12
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  4. 19
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs
  5. 39
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

4
Directory.Packages.props

@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
<PackageVersion Include="JunitXml.TestLogger" Version="3.1.12" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.6" />
<PackageVersion Include="McMaster.Extensions.Hosting.CommandLine" Version="4.1.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.9.2" />
<PackageVersion Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta2-22171-02" />
<PackageVersion Include="Microsoft.DiaSymReader" Version="1.4.0" />
<PackageVersion Include="Microsoft.DiaSymReader.Native" Version="17.0.0-beta1.21524.1" />

4
ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs

@ -16,12 +16,10 @@ @@ -16,12 +16,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
@ -361,7 +359,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -361,7 +359,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
private bool MatchRoslynSwitchOnString()
{
var insns = analysis.RootBlock.Instructions;
return insns.Count >= 3 && SwitchOnStringTransform.MatchComputeStringHashCall(insns[insns.Count - 3], analysis.SwitchVariable, out var switchLdLoc);
return insns.Count >= 3 && SwitchOnStringTransform.MatchComputeStringOrReadOnlySpanHashCall(insns[insns.Count - 3], analysis.SwitchVariable, out _);
}
/// <summary>

12
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -274,6 +274,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -274,6 +274,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitCall(Call inst)
{
if (NullableLiftingTransform.MatchGetValueOrDefault(inst, out var nullableValue, out var fallback)
&& SemanticHelper.IsPure(fallback.Flags))
{
context.Step("call Nullable{T}.GetValueOrDefault(a, b) -> a ?? b", inst);
var ldObj = new LdObj(nullableValue, inst.Method.DeclaringType);
var replacement = new NullCoalescingInstruction(NullCoalescingKind.NullableWithValueFallback, ldObj, fallback) {
UnderlyingResultType = fallback.ResultType
};
inst.ReplaceWith(replacement.WithILRange(inst));
replacement.AcceptVisitor(this);
return;
}
base.VisitCall(inst);
TransformAssignment.HandleCompoundAssign(inst, context);
}

19
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -1047,6 +1046,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1047,6 +1046,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
/// <summary>
/// Matches 'call nullableValue.GetValueOrDefault(fallback)'
/// </summary>
internal static bool MatchGetValueOrDefault(ILInstruction inst, out ILInstruction nullableValue, out ILInstruction fallback)
{
nullableValue = null;
fallback = null;
if (!(inst is Call call))
return false;
if (call.Method.Name != "GetValueOrDefault" || call.Arguments.Count != 2)
return false;
if (call.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)
return false;
nullableValue = call.Arguments[0];
fallback = call.Arguments[1];
return true;
}
/// <summary>
/// Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)'
/// </summary>

39
ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

@ -294,6 +294,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -294,6 +294,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
keepAssignmentBefore = true;
switchValue = new LdLoc(switchValueVar);
}
if (!switchValueVar.Type.IsKnownType(KnownTypeCode.String))
{
if (!context.Settings.SwitchOnReadOnlySpanChar)
return false;
if (!switchValueVar.Type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)
&& !switchValueVar.Type.IsKnownType(KnownTypeCode.SpanOfT))
{
return false;
}
}
// if instruction must be followed by a branch to the next case
if (!nextCaseJump.MatchBranch(out Block currentCaseBlock))
return false;
@ -335,7 +345,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -335,7 +345,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
int offset = firstBlock == null ? 1 : 0;
var sections = new List<SwitchSection>(values.Skip(offset).SelectWithIndex((index, s) => new SwitchSection { Labels = new LongSet(index), Body = s.Item2 is Block b ? new Branch(b) : s.Item2.Clone() }));
sections.Add(new SwitchSection { Labels = new LongSet(new LongInterval(0, sections.Count)).Invert(), Body = currentCaseBlock != null ? (ILInstruction)new Branch(currentCaseBlock) : new Leave((BlockContainer)nextCaseBlock) });
var stringToInt = new StringToInt(switchValue, values.Skip(offset).Select(item => item.Item1).ToArray(), context.TypeSystem.FindType(KnownTypeCode.String));
var stringToInt = new StringToInt(switchValue, values.Skip(offset).Select(item => item.Item1).ToArray(), switchValueVar.Type);
var inst = new SwitchInstruction(stringToInt);
inst.Sections.AddRange(sections);
if (removeExtraLoad)
@ -1008,7 +1018,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1008,7 +1018,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!(switchBlockInstructionsOffset + 1 < switchBlockInstructions.Count
&& switchBlockInstructions[switchBlockInstructionsOffset + 1] is SwitchInstruction switchInst
&& switchInst.Value.MatchLdLoc(out var switchValueVar)
&& MatchComputeStringHashCall(switchBlockInstructions[switchBlockInstructionsOffset],
&& MatchComputeStringOrReadOnlySpanHashCall(switchBlockInstructions[switchBlockInstructionsOffset],
switchValueVar, out LdLoc switchValueLoad)))
{
return false;
@ -1643,19 +1653,28 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1643,19 +1653,28 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
/// <summary>
/// Matches 'stloc(targetVar, call ComputeStringHash(ldloc switchValue))'
/// Matches
/// 'stloc(targetVar, call ComputeStringHash(ldloc switchValue))'
/// - or -
/// 'stloc(targetVar, call ComputeSpanHash(ldloc switchValue))'
/// - or -
/// 'stloc(targetVar, call ComputeReadOnlySpanHash(ldloc switchValue))'
/// </summary>
internal static bool MatchComputeStringHashCall(ILInstruction inst, ILVariable targetVar, out LdLoc switchValue)
internal static bool MatchComputeStringOrReadOnlySpanHashCall(ILInstruction inst, ILVariable targetVar, out LdLoc switchValue)
{
switchValue = null;
if (!inst.MatchStLoc(targetVar, out var value))
return false;
if (!(value is Call c && c.Arguments.Count == 1 && c.Method.Name == "ComputeStringHash" && c.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass()))
return false;
if (!(c.Arguments[0] is LdLoc))
return false;
switchValue = (LdLoc)c.Arguments[0];
return true;
if (value is Call c && c.Arguments.Count == 1
&& c.Method.Name is "ComputeStringHash" or "ComputeSpanHash" or "ComputeReadOnlySpanHash"
&& c.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
{
if (c.Arguments[0] is not LdLoc ldloc)
return false;
switchValue = ldloc;
return true;
}
return false;
}
/// <summary>

Loading…
Cancel
Save