Skip to content

Commit

Permalink
Merge pull request #3058 from icsharpcode/switch-on-readonlyspan-char
Browse files Browse the repository at this point in the history
  • Loading branch information
siegfriedpammer authored Aug 24, 2023
2 parents 7c8b497 + 70616b3 commit a60b92e
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 81 deletions.
5 changes: 4 additions & 1 deletion ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ public static async Task<CompilerResults> CompileVB(string sourceFileName, Compi
var vbcPath = roslynToolset.GetVBCompiler(roslynVersion);

IEnumerable<string> references;
string libPath;
if ((flags & CompilerOptions.UseRoslynMask) != 0 && (flags & CompilerOptions.TargetNet40) == 0)
{
references = coreDefaultReferences.Select(r => "-r:\"" + r + "\"");
libPath = coreRefAsmPath;
}
else
{
references = defaultReferences.Select(r => "-r:\"" + r + "\"");
libPath = RefAsmPath;
}
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
Expand Down Expand Up @@ -116,7 +119,7 @@ public static async Task<CompilerResults> CompileVB(string sourceFileName, Compi
}

var command = Cli.Wrap(vbcPath)
.WithArguments($"{otherOptions}{string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithArguments($"{otherOptions}-libpath:\"{libPath}\" {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithValidation(CommandResultValidation.None);
Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}");

Expand Down
1 change: 1 addition & 0 deletions ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ private static string ReplacePrivImplDetails(string il)
"System.Linq.Expressions.dll",
"System.Linq.Queryable.dll",
"System.IO.FileSystem.Watcher.dll",
"System.Memory.dll",
"System.Threading.dll",
"System.Threading.Thread.dll",
"System.Runtime.dll",
Expand Down
49 changes: 49 additions & 0 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1509,5 +1509,54 @@ public static void Issue2763(int value)
break;
}
}


#if CS110 && NET70
public static string SwitchOverReadOnlySpanChar1(ReadOnlySpan<char> text)
{
Console.WriteLine("SwitchOverReadOnlySpanChar1:");
switch (text)
{
case "First case":
return "Text1";
case "Second case":
case "2nd case":
return "Text2";
case "Third case":
return "Text3";
case "Fourth case":
return "Text4";
case "Fifth case":
return "Text5";
case "Sixth case":
return "Text6";
default:
return "Default";
}
}

public static string SwitchOverSpanChar1(Span<char> text)
{
Console.WriteLine("SwitchOverSpanChar1:");
switch (text)
{
case "First case":
return "Text1";
case "Second case":
case "2nd case":
return "Text2";
case "Third case":
return "Text3";
case "Fourth case":
return "Text4";
case "Fifth case":
return "Text5";
case "Sixth case":
return "Text6";
default:
return "Default";
}
}
#endif
}
}
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3898,7 +3898,7 @@ protected internal override TranslatedExpression VisitSwitchInstruction(SwitchIn
{
value = Translate(strToInt.Argument)
.ConvertTo(
typeSystem.FindType(KnownTypeCode.String),
strToInt.ExpectedType,
this,
allowImplicitConversion: false // switch-expression does not support implicit conversions
);
Expand Down
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ SwitchStatement TranslateSwitch(BlockContainer switchContainer, SwitchInstructio
{
value = exprBuilder.Translate(strToInt.Argument)
.ConvertTo(
typeSystem.FindType(KnownTypeCode.String),
strToInt.ExpectedType,
exprBuilder,
// switch statement does support implicit conversions in general, however, the rules are
// not very intuitive and in order to prevent bugs, we emit an explicit cast.
Expand Down
18 changes: 18 additions & 0 deletions ICSharpCode.Decompiler/DecompilerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,24 @@ public bool Utf8StringLiterals {
}
}

bool switchOnReadOnlySpanChar = true;

/// <summary>
/// Gets/Sets whether to use C# 11.0 switch on (ReadOnly)Span&lt;char&gt;
/// </summary>
[Category("C# 11.0 / VS 2022.4")]
[Description("DecompilerSettings.SwitchOnReadOnlySpanChar")]
public bool SwitchOnReadOnlySpanChar {
get { return switchOnReadOnlySpanChar; }
set {
if (switchOnReadOnlySpanChar != value)
{
switchOnReadOnlySpanChar = value;
OnPropertyChanged();
}
}
}

bool unsignedRightShift = true;

/// <summary>
Expand Down
15 changes: 11 additions & 4 deletions ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,26 @@

using System.Collections.Generic;

using ICSharpCode.Decompiler.TypeSystem;

namespace ICSharpCode.Decompiler.IL
{
partial class StringToInt
{
public List<(string? Key, int Value)> Map { get; }

public StringToInt(ILInstruction argument, List<(string? Key, int Value)> map)
public IType ExpectedType { get; }

public StringToInt(ILInstruction argument, List<(string? Key, int Value)> map, IType expectedType)
: base(OpCode.StringToInt)
{
this.Argument = argument;
this.Map = map;
this.ExpectedType = expectedType;
}

public StringToInt(ILInstruction argument, string?[] map)
: this(argument, ArrayToDictionary(map))
public StringToInt(ILInstruction argument, string?[] map, IType expectedType)
: this(argument, ArrayToDictionary(map), expectedType)
{
}

Expand All @@ -51,7 +56,9 @@ public StringToInt(ILInstruction argument, string?[] map)
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
WriteILRange(output, options);
output.Write("string.to.int (");
output.Write("string.to.int ");
ExpectedType.WriteTo(output);
output.Write('(');
Argument.WriteTo(output, options);
output.Write(", { ");
int i = 0;
Expand Down
Loading

0 comments on commit a60b92e

Please sign in to comment.