Browse Source

Add DecompilerSettings constructor that takes a language version.

pull/1087/head
Daniel Grunwald 7 years ago
parent
commit
8a589b2fd2
  1. 13
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 20
      ICSharpCode.Decompiler/CSharp/CSharpLanguageVersion.cs
  3. 78
      ICSharpCode.Decompiler/DecompilerSettings.cs
  4. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  5. 2
      ICSharpCode.Decompiler/IL/ControlFlow/AwaitInCatchTransform.cs
  6. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

13
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -194,7 +194,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -194,7 +194,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var preprocessorSymbols = GetPreprocessorSymbols(flags);
if (flags.HasFlag(CSharpCompilerOptions.UseRoslyn)) {
var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray(), languageVersion: LanguageVersion.Latest);
var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray(), languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, defaultReferences.Value,
@ -297,14 +297,11 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -297,14 +297,11 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
internal static DecompilerSettings GetSettings(CSharpCompilerOptions cscOptions)
{
var settings = new DecompilerSettings();
if ((cscOptions & CSharpCompilerOptions.UseRoslyn) == 0) {
// disable C# features not available in legacy compiler
settings.NullPropagation = false;
settings.StringInterpolation = false;
settings.UseExpressionBodyForCalculatedGetterOnlyProperties = false;
if (cscOptions.HasFlag(CSharpCompilerOptions.UseRoslyn)) {
return new DecompilerSettings(CSharp.LanguageVersion.Latest);
} else {
return new DecompilerSettings(CSharp.LanguageVersion.CSharp5);
}
return settings;
}
public static CSharpDecompiler GetDecompilerForSnippet(string csharpText)

20
ICSharpCode.Decompiler/CSharp/CSharpLanguageVersion.cs

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ICSharpCode.Decompiler.CSharp
{
public enum LanguageVersion
{
CSharp1 = 1,
CSharp2 = 2,
CSharp3 = 3,
CSharp4 = 4,
CSharp5 = 5,
CSharp6 = 6,
CSharp7 = 7,
CSharp7_1 = 701,
CSharp7_2 = 702,
Latest = 0x7FFFFFFF
}
}

78
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -28,6 +28,52 @@ namespace ICSharpCode.Decompiler @@ -28,6 +28,52 @@ namespace ICSharpCode.Decompiler
/// </summary>
public class DecompilerSettings : INotifyPropertyChanged
{
/// <summary>
/// Equivalent to <c>new DecompilerSettings(LanguageVersion.Latest)</c>
/// </summary>
public DecompilerSettings()
{
}
/// <summary>
/// Creates a new DecompilerSettings instance with initial settings
/// appropriate for the specified language version.
/// </summary>
/// <remarks>
/// This does not imply that the resulting
/// </remarks>
public DecompilerSettings(CSharp.LanguageVersion languageVersion)
{
// By default, all decompiler features are enabled.
// Disable some of them based on language version:
if (languageVersion < CSharp.LanguageVersion.CSharp2) {
anonymousMethods = false;
liftNullables = false;
yieldReturn = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp3) {
anonymousTypes = false;
objectCollectionInitializers = false;
automaticProperties = false;
queryExpressions = false;
expressionTrees = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp4) {
// * dynamic (not supported yet)
// * named and optional arguments (not supported yet)
}
if (languageVersion < CSharp.LanguageVersion.CSharp5) {
asyncAwait = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp6) {
awaitInCatchFinally = false;
useExpressionBodyForCalculatedGetterOnlyProperties = false;
nullPropagation = false;
stringInterpolation = false;
dictionaryInitializers = false;
}
}
bool anonymousMethods = true;
/// <summary>
@ -103,6 +149,22 @@ namespace ICSharpCode.Decompiler @@ -103,6 +149,22 @@ namespace ICSharpCode.Decompiler
}
}
bool awaitInCatchFinally = true;
/// <summary>
/// Decompile await in catch/finally blocks.
/// Only has an effect if <see cref="AsyncAwait"/> is enabled.
/// </summary>
public bool AwaitInCatchFinally {
get { return awaitInCatchFinally; }
set {
if (awaitInCatchFinally != value) {
awaitInCatchFinally = value;
OnPropertyChanged();
}
}
}
bool fixedBuffers = true;
/// <summary>
@ -352,6 +414,22 @@ namespace ICSharpCode.Decompiler @@ -352,6 +414,22 @@ namespace ICSharpCode.Decompiler
}
}
bool dictionaryInitializers = true;
/// <summary>
/// Gets/Sets whether to use C# 6.0 dictionary initializers.
/// Only has an effect if ObjectOrCollectionInitializers is enabled.
/// </summary>
public bool DictionaryInitializers {
get { return dictionaryInitializers; }
set {
if (dictionaryInitializers != value) {
dictionaryInitializers = value;
OnPropertyChanged();
}
}
}
bool stringInterpolation = true;
/// <summary>

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -58,6 +58,7 @@ @@ -58,6 +58,7 @@
<ItemGroup>
<Compile Include="CSharp\Annotations.cs" />
<Compile Include="CSharp\CallBuilder.cs" />
<Compile Include="CSharp\CSharpLanguageVersion.cs" />
<Compile Include="CSharp\SequencePointBuilder.cs" />
<Compile Include="CSharp\Syntax\AstNode.cs" />
<Compile Include="CSharp\Syntax\AstNodeCollection.cs" />

2
ICSharpCode.Decompiler/IL/ControlFlow/AwaitInCatchTransform.cs

@ -31,6 +31,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -31,6 +31,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
{
public static void Run(ILFunction function, ILTransformContext context)
{
if (!context.Settings.AwaitInCatchFinally)
return;
HashSet<BlockContainer> changedContainers = new HashSet<BlockContainer>();
// analyze all try-catch statements in the function

2
ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

@ -168,6 +168,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -168,6 +168,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// in the list of possible index variables.
// Index variables are used to implement dictionary initializers.
if (instructions[pos] is StLoc stloc && stloc.Variable.Kind == VariableKind.Local && stloc.Variable.IsSingleDefinition) {
if (!context.Settings.DictionaryInitializers)
return false;
if (stloc.Value.Descendants.OfType<IInstructionWithVariableOperand>().Any(ld => ld.Variable == target && (ld is LdLoc || ld is LdLoca)))
return false;
possibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value));

Loading…
Cancel
Save